diff mbox

[PATCHv3,13/15] Thermal: Remove throttling logic out of thermal_sys.c

Message ID 1346500296-25200-14-git-send-email-durgadoss.r@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

durgadoss.r@intel.com Sept. 1, 2012, 11:51 a.m. UTC
This patch removes the throttling logic out of
thermal_sys.c; also refactors the code into smaller
functions so that are easy to read/maintain.
 * Seperates the handling of critical and non-critical trips
 * Re-arranges the set_polling and device_check methods, so
   that all related functions are arranged in one place.
 * Removes the 'do_update' and 'trip_update' method, as part
   of moving the throttling logic out of thermal_sys.c

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |  313 +++++++++++++++--------------------------
 1 file changed, 112 insertions(+), 201 deletions(-)

Comments

Zhang Rui Sept. 10, 2012, 8:44 a.m. UTC | #1
On ?, 2012-09-01 at 17:21 +0530, Durgadoss R wrote:
> This patch removes the throttling logic out of
> thermal_sys.c; also refactors the code into smaller
> functions so that are easy to read/maintain.
>  * Seperates the handling of critical and non-critical trips
>  * Re-arranges the set_polling and device_check methods, so
>    that all related functions are arranged in one place.
>  * Removes the 'do_update' and 'trip_update' method, as part
>    of moving the throttling logic out of thermal_sys.c
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/thermal/thermal_sys.c |  313 +++++++++++++++--------------------------
>  1 file changed, 112 insertions(+), 201 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 93672aa..086c1c9 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -315,6 +315,118 @@ exit:
>  	mutex_unlock(&thermal_list_lock);
>  }
>  
> +static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> +					    int delay)
> +{
> +	cancel_delayed_work(&(tz->poll_queue));
> +
> +	if (!delay)
> +		return;
> +
> +	if (delay > 1000)
> +		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
> +				      round_jiffies(msecs_to_jiffies(delay)));
> +	else
> +		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
> +				      msecs_to_jiffies(delay));
> +}
> +
> +static void monitor_thermal_zone(struct thermal_zone_device *tz)
> +{
> +	mutex_lock(&tz->lock);
> +
> +	if (tz->passive)
> +		thermal_zone_device_set_polling(tz, tz->passive_delay);
> +	else if (tz->polling_delay)
> +		thermal_zone_device_set_polling(tz, tz->polling_delay);
> +	else
> +		thermal_zone_device_set_polling(tz, 0);
> +
> +	mutex_unlock(&tz->lock);
> +}
> +
> +static void handle_non_critical_trips(struct thermal_zone_device *tz,
> +			int trip, enum thermal_trip_type trip_type)
> +{
> +	tz->governor->throttle(tz, trip);
> +}
here is the problem, we must make sure every registered thermal zone
have a governor when it is running, right?

then the default governor must always be built in.
We can have a Kconfig option for step_wise, but we should not make it
configurable by users.
or we can use prompt to get the default governor at build time. say

choice
        prompt "Default thermal governor"
        default THERMAL_DEFAULT_GOV_STEP_WISE
        help
          This option sets which thermal governor shall be loaded at
          startup.

config THERMAL_DEFAULT_GOV_STEP_WISE
        bool "step-wise"
        select THERMAL_GOV_STEP_WISE
        help
          Use the thermal governor 'step-wise' as default.blabla


thanks,
rui

> +
> +static void handle_critical_trips(struct thermal_zone_device *tz,
> +				int trip, enum thermal_trip_type trip_type)
> +{
> +	long trip_temp;
> +
> +	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +
> +	/* If we have not crossed the trip_temp, we do not care. */
> +	if (tz->temperature < trip_temp)
> +		return;
> +
> +	if (tz->ops->notify)
> +		tz->ops->notify(tz, trip, trip_type);
> +
> +	if (trip_type == THERMAL_TRIP_CRITICAL) {
> +		pr_emerg("Critical temperature reached(%d C),shutting down\n",
> +			 tz->temperature / 1000);
> +		orderly_poweroff(true);
> +	}
> +}
> +
> +static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
> +{
> +	enum thermal_trip_type type;
> +
> +	tz->ops->get_trip_type(tz, trip, &type);
> +
> +	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
> +		handle_critical_trips(tz, trip, type);
> +	else
> +		handle_non_critical_trips(tz, trip, type);
> +	/*
> +	 * Alright, we handled this trip successfully.
> +	 * So, start monitoring again.
> +	 */
> +	monitor_thermal_zone(tz);
> +}
> +
> +static void update_temperature(struct thermal_zone_device *tz)
> +{
> +	long temp;
> +	int ret;
> +
> +	mutex_lock(&tz->lock);
> +
> +	ret = tz->ops->get_temp(tz, &temp);
> +	if (ret) {
> +		pr_warn("failed to read out thermal zone %d\n", tz->id);
> +		return;
> +	}
> +
> +	tz->last_temperature = tz->temperature;
> +	tz->temperature = temp;
> +
> +	mutex_unlock(&tz->lock);
> +}
> +
> +void thermal_zone_device_update(struct thermal_zone_device *tz)
> +{
> +	int count;
> +
> +	update_temperature(tz);
> +
> +	for (count = 0; count < tz->trips; count++)
> +		handle_thermal_trip(tz, count);
> +}
> +EXPORT_SYMBOL(thermal_zone_device_update);
> +
> +static void thermal_zone_device_check(struct work_struct *work)
> +{
> +	struct thermal_zone_device *tz = container_of(work, struct
> +						      thermal_zone_device,
> +						      poll_queue.work);
> +	thermal_zone_device_update(tz);
> +}
> +
>  /* sys I/F for thermal zone */
>  
>  #define to_thermal_zone(_dev) \
> @@ -936,30 +1048,6 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
>  }
>  #endif
>  
> -static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> -					    int delay)
> -{
> -	cancel_delayed_work(&(tz->poll_queue));
> -
> -	if (!delay)
> -		return;
> -
> -	if (delay > 1000)
> -		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
> -				      round_jiffies(msecs_to_jiffies(delay)));
> -	else
> -		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
> -				      msecs_to_jiffies(delay));
> -}
> -
> -static void thermal_zone_device_check(struct work_struct *work)
> -{
> -	struct thermal_zone_device *tz = container_of(work, struct
> -						      thermal_zone_device,
> -						      poll_queue.work);
> -	thermal_zone_device_update(tz);
> -}
> -
>  /**
>   * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
>   * @tz:		thermal zone device
> @@ -1283,183 +1371,6 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
>  }
>  EXPORT_SYMBOL(thermal_cdev_update);
>  
> -static void thermal_zone_do_update(struct thermal_zone_device *tz)
> -{
> -	struct thermal_instance *instance;
> -
> -	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
> -		thermal_cdev_update(instance->cdev);
> -}
> -
> -/*
> - * Cooling algorithm for both active and passive cooling
> - *
> - * 1. if the temperature is higher than a trip point,
> - *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
> - *       state for this trip point
> - *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
> - *       state for this trip point
> - *
> - * 2. if the temperature is lower than a trip point, use lower
> - *    cooling state for this trip point
> - *
> - * Note that this behaves the same as the previous passive cooling
> - * algorithm.
> - */
> -
> -static void thermal_zone_trip_update(struct thermal_zone_device *tz,
> -				     int trip, long temp)
> -{
> -	struct thermal_instance *instance;
> -	struct thermal_cooling_device *cdev = NULL;
> -	unsigned long cur_state, max_state;
> -	long trip_temp;
> -	enum thermal_trip_type trip_type;
> -	enum thermal_trend trend;
> -
> -	if (trip == THERMAL_TRIPS_NONE) {
> -		trip_temp = tz->forced_passive;
> -		trip_type = THERMAL_TRIPS_NONE;
> -	} else {
> -		tz->ops->get_trip_temp(tz, trip, &trip_temp);
> -		tz->ops->get_trip_type(tz, trip, &trip_type);
> -	}
> -
> -	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> -		/*
> -		 * compare the current temperature and previous temperature
> -		 * to get the thermal trend, if no special requirement
> -		 */
> -		if (tz->temperature > tz->last_temperature)
> -			trend = THERMAL_TREND_RAISING;
> -		else if (tz->temperature < tz->last_temperature)
> -			trend = THERMAL_TREND_DROPPING;
> -		else
> -			trend = THERMAL_TREND_STABLE;
> -	}
> -
> -	if (temp >= trip_temp) {
> -		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> -			if (instance->trip != trip)
> -				continue;
> -
> -			cdev = instance->cdev;
> -
> -			cdev->ops->get_cur_state(cdev, &cur_state);
> -			cdev->ops->get_max_state(cdev, &max_state);
> -
> -			if (trend == THERMAL_TREND_RAISING) {
> -				cur_state = cur_state < instance->upper ?
> -					    (cur_state + 1) : instance->upper;
> -			} else if (trend == THERMAL_TREND_DROPPING) {
> -				cur_state = cur_state > instance->lower ?
> -				    (cur_state - 1) : instance->lower;
> -			}
> -
> -			/* activate a passive thermal instance */
> -			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> -			     trip_type == THERMAL_TRIPS_NONE) &&
> -			     instance->target == THERMAL_NO_TARGET)
> -				tz->passive++;
> -
> -			instance->target = cur_state;
> -			cdev->updated = false; /* cooling device needs update */
> -		}
> -	} else {	/* below trip */
> -		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> -			if (instance->trip != trip)
> -				continue;
> -
> -			/* Do not use the inactive thermal instance */
> -			if (instance->target == THERMAL_NO_TARGET)
> -				continue;
> -			cdev = instance->cdev;
> -			cdev->ops->get_cur_state(cdev, &cur_state);
> -
> -			cur_state = cur_state > instance->lower ?
> -				    (cur_state - 1) : THERMAL_NO_TARGET;
> -
> -			/* deactivate a passive thermal instance */
> -			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> -			     trip_type == THERMAL_TRIPS_NONE) &&
> -			     cur_state == THERMAL_NO_TARGET)
> -				tz->passive--;
> -			instance->target = cur_state;
> -			cdev->updated = false; /* cooling device needs update */
> -		}
> -	}
> -
> -	return;
> -}
> -/**
> - * thermal_zone_device_update - force an update of a thermal zone's state
> - * @ttz:	the thermal zone to update
> - */
> -
> -void thermal_zone_device_update(struct thermal_zone_device *tz)
> -{
> -	int count, ret = 0;
> -	long temp, trip_temp;
> -	enum thermal_trip_type trip_type;
> -
> -	mutex_lock(&tz->lock);
> -
> -	if (tz->ops->get_temp(tz, &temp)) {
> -		/* get_temp failed - retry it later */
> -		pr_warn("failed to read out thermal zone %d\n", tz->id);
> -		goto leave;
> -	}
> -
> -	tz->last_temperature = tz->temperature;
> -	tz->temperature = temp;
> -
> -	for (count = 0; count < tz->trips; count++) {
> -		tz->ops->get_trip_type(tz, count, &trip_type);
> -		tz->ops->get_trip_temp(tz, count, &trip_temp);
> -
> -		switch (trip_type) {
> -		case THERMAL_TRIP_CRITICAL:
> -			if (temp >= trip_temp) {
> -				if (tz->ops->notify)
> -					ret = tz->ops->notify(tz, count,
> -							      trip_type);
> -				if (!ret) {
> -					pr_emerg("Critical temperature reached (%ld C), shutting down\n",
> -						 temp/1000);
> -					orderly_poweroff(true);
> -				}
> -			}
> -			break;
> -		case THERMAL_TRIP_HOT:
> -			if (temp >= trip_temp)
> -				if (tz->ops->notify)
> -					tz->ops->notify(tz, count, trip_type);
> -			break;
> -		case THERMAL_TRIP_ACTIVE:
> -			thermal_zone_trip_update(tz, count, temp);
> -			break;
> -		case THERMAL_TRIP_PASSIVE:
> -			if (temp >= trip_temp || tz->passive)
> -				thermal_zone_trip_update(tz, count, temp);
> -			break;
> -		}
> -	}
> -
> -	if (tz->forced_passive)
> -		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
> -	thermal_zone_do_update(tz);
> -
> -leave:
> -	if (tz->passive)
> -		thermal_zone_device_set_polling(tz, tz->passive_delay);
> -	else if (tz->polling_delay)
> -		thermal_zone_device_set_polling(tz, tz->polling_delay);
> -	else
> -		thermal_zone_device_set_polling(tz, 0);
> -	mutex_unlock(&tz->lock);
> -}
> -EXPORT_SYMBOL(thermal_zone_device_update);
> -
>  /**
>   * create_trip_attrs - create attributes for trip points
>   * @tz:		the thermal zone device


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
durgadoss.r@intel.com Sept. 10, 2012, 8:56 a.m. UTC | #2
Hi Rui,

> -----Original Message-----

> From: Zhang, Rui

> Sent: Monday, September 10, 2012 2:14 PM

> To: R, Durgadoss

> Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com

> Subject: Re: [PATCHv3 13/15] Thermal: Remove throttling logic out of

> thermal_sys.c

[cut.]

> > +

> > +static void handle_non_critical_trips(struct thermal_zone_device *tz,

> > +			int trip, enum thermal_trip_type trip_type)

> > +{

> > +	tz->governor->throttle(tz, trip);

> > +}

> here is the problem, we must make sure every registered thermal zone

> have a governor when it is running, right?


Yes, agree with you. Had some thoughts here, but wanted to get your opinion
before I implemented them.

1. We can make the default governor as 'user space', and make it load inside
thermal_sys.c (so that every zone will always have a default governor)

2. All other governors, that are implemented in a separate .c file can be
optional i.e. left to the user to select/deselect.

IMO, this will make our implementation easier and cleaner.
What do you think ?

Thanks,
Durga

> 

> then the default governor must always be built in.

> We can have a Kconfig option for step_wise, but we should not make it

> configurable by users.

> or we can use prompt to get the default governor at build time. say

> 

> choice

>         prompt "Default thermal governor"

>         default THERMAL_DEFAULT_GOV_STEP_WISE

>         help

>           This option sets which thermal governor shall be loaded at

>           startup.

> 

> config THERMAL_DEFAULT_GOV_STEP_WISE

>         bool "step-wise"

>         select THERMAL_GOV_STEP_WISE

>         help

>           Use the thermal governor 'step-wise' as default.blabla

> 

> 

> thanks,

> rui

> 

> > +

> > +static void handle_critical_trips(struct thermal_zone_device *tz,

> > +				int trip, enum thermal_trip_type trip_type)

> > +{

> > +	long trip_temp;

> > +

> > +	tz->ops->get_trip_temp(tz, trip, &trip_temp);

> > +

> > +	/* If we have not crossed the trip_temp, we do not care. */

> > +	if (tz->temperature < trip_temp)

> > +		return;

> > +

> > +	if (tz->ops->notify)

> > +		tz->ops->notify(tz, trip, trip_type);

> > +

> > +	if (trip_type == THERMAL_TRIP_CRITICAL) {

> > +		pr_emerg("Critical temperature reached(%d C),shutting

> down\n",

> > +			 tz->temperature / 1000);

> > +		orderly_poweroff(true);

> > +	}

> > +}

> > +

> > +static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)

> > +{

> > +	enum thermal_trip_type type;

> > +

> > +	tz->ops->get_trip_type(tz, trip, &type);

> > +

> > +	if (type == THERMAL_TRIP_CRITICAL || type ==

> THERMAL_TRIP_HOT)

> > +		handle_critical_trips(tz, trip, type);

> > +	else

> > +		handle_non_critical_trips(tz, trip, type);

> > +	/*

> > +	 * Alright, we handled this trip successfully.

> > +	 * So, start monitoring again.

> > +	 */

> > +	monitor_thermal_zone(tz);

> > +}

> > +

> > +static void update_temperature(struct thermal_zone_device *tz)

> > +{

> > +	long temp;

> > +	int ret;

> > +

> > +	mutex_lock(&tz->lock);

> > +

> > +	ret = tz->ops->get_temp(tz, &temp);

> > +	if (ret) {

> > +		pr_warn("failed to read out thermal zone %d\n", tz->id);

> > +		return;

> > +	}

> > +

> > +	tz->last_temperature = tz->temperature;

> > +	tz->temperature = temp;

> > +

> > +	mutex_unlock(&tz->lock);

> > +}

> > +

> > +void thermal_zone_device_update(struct thermal_zone_device *tz)

> > +{

> > +	int count;

> > +

> > +	update_temperature(tz);

> > +

> > +	for (count = 0; count < tz->trips; count++)

> > +		handle_thermal_trip(tz, count);

> > +}

> > +EXPORT_SYMBOL(thermal_zone_device_update);

> > +

> > +static void thermal_zone_device_check(struct work_struct *work)

> > +{

> > +	struct thermal_zone_device *tz = container_of(work, struct

> > +						      thermal_zone_device,

> > +						      poll_queue.work);

> > +	thermal_zone_device_update(tz);

> > +}

> > +

> >  /* sys I/F for thermal zone */

> >

> >  #define to_thermal_zone(_dev) \

> > @@ -936,30 +1048,6 @@ thermal_remove_hwmon_sysfs(struct

> thermal_zone_device *tz)

> >  }

> >  #endif

> >

> > -static void thermal_zone_device_set_polling(struct thermal_zone_device

> *tz,

> > -					    int delay)

> > -{

> > -	cancel_delayed_work(&(tz->poll_queue));

> > -

> > -	if (!delay)

> > -		return;

> > -

> > -	if (delay > 1000)

> > -		queue_delayed_work(system_freezable_wq, &(tz-

> >poll_queue),

> > -				      round_jiffies(msecs_to_jiffies(delay)));

> > -	else

> > -		queue_delayed_work(system_freezable_wq, &(tz-

> >poll_queue),

> > -				      msecs_to_jiffies(delay));

> > -}

> > -

> > -static void thermal_zone_device_check(struct work_struct *work)

> > -{

> > -	struct thermal_zone_device *tz = container_of(work, struct

> > -						      thermal_zone_device,

> > -						      poll_queue.work);

> > -	thermal_zone_device_update(tz);

> > -}

> > -

> >  /**

> >   * thermal_zone_bind_cooling_device - bind a cooling device to a thermal

> zone

> >   * @tz:		thermal zone device

> > @@ -1283,183 +1371,6 @@ void thermal_cdev_update(struct

> thermal_cooling_device *cdev)

> >  }

> >  EXPORT_SYMBOL(thermal_cdev_update);

> >

> > -static void thermal_zone_do_update(struct thermal_zone_device *tz)

> > -{

> > -	struct thermal_instance *instance;

> > -

> > -	list_for_each_entry(instance, &tz->thermal_instances, tz_node)

> > -		thermal_cdev_update(instance->cdev);

> > -}

> > -

> > -/*

> > - * Cooling algorithm for both active and passive cooling

> > - *

> > - * 1. if the temperature is higher than a trip point,

> > - *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling

> > - *       state for this trip point

> > - *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling

> > - *       state for this trip point

> > - *

> > - * 2. if the temperature is lower than a trip point, use lower

> > - *    cooling state for this trip point

> > - *

> > - * Note that this behaves the same as the previous passive cooling

> > - * algorithm.

> > - */

> > -

> > -static void thermal_zone_trip_update(struct thermal_zone_device *tz,

> > -				     int trip, long temp)

> > -{

> > -	struct thermal_instance *instance;

> > -	struct thermal_cooling_device *cdev = NULL;

> > -	unsigned long cur_state, max_state;

> > -	long trip_temp;

> > -	enum thermal_trip_type trip_type;

> > -	enum thermal_trend trend;

> > -

> > -	if (trip == THERMAL_TRIPS_NONE) {

> > -		trip_temp = tz->forced_passive;

> > -		trip_type = THERMAL_TRIPS_NONE;

> > -	} else {

> > -		tz->ops->get_trip_temp(tz, trip, &trip_temp);

> > -		tz->ops->get_trip_type(tz, trip, &trip_type);

> > -	}

> > -

> > -	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {

> > -		/*

> > -		 * compare the current temperature and previous

> temperature

> > -		 * to get the thermal trend, if no special requirement

> > -		 */

> > -		if (tz->temperature > tz->last_temperature)

> > -			trend = THERMAL_TREND_RAISING;

> > -		else if (tz->temperature < tz->last_temperature)

> > -			trend = THERMAL_TREND_DROPPING;

> > -		else

> > -			trend = THERMAL_TREND_STABLE;

> > -	}

> > -

> > -	if (temp >= trip_temp) {

> > -		list_for_each_entry(instance, &tz->thermal_instances,

> tz_node) {

> > -			if (instance->trip != trip)

> > -				continue;

> > -

> > -			cdev = instance->cdev;

> > -

> > -			cdev->ops->get_cur_state(cdev, &cur_state);

> > -			cdev->ops->get_max_state(cdev, &max_state);

> > -

> > -			if (trend == THERMAL_TREND_RAISING) {

> > -				cur_state = cur_state < instance->upper ?

> > -					    (cur_state + 1) : instance->upper;

> > -			} else if (trend == THERMAL_TREND_DROPPING) {

> > -				cur_state = cur_state > instance->lower ?

> > -				    (cur_state - 1) : instance->lower;

> > -			}

> > -

> > -			/* activate a passive thermal instance */

> > -			if ((trip_type == THERMAL_TRIP_PASSIVE ||

> > -			     trip_type == THERMAL_TRIPS_NONE) &&

> > -			     instance->target == THERMAL_NO_TARGET)

> > -				tz->passive++;

> > -

> > -			instance->target = cur_state;

> > -			cdev->updated = false; /* cooling device needs

> update */

> > -		}

> > -	} else {	/* below trip */

> > -		list_for_each_entry(instance, &tz->thermal_instances,

> tz_node) {

> > -			if (instance->trip != trip)

> > -				continue;

> > -

> > -			/* Do not use the inactive thermal instance */

> > -			if (instance->target == THERMAL_NO_TARGET)

> > -				continue;

> > -			cdev = instance->cdev;

> > -			cdev->ops->get_cur_state(cdev, &cur_state);

> > -

> > -			cur_state = cur_state > instance->lower ?

> > -				    (cur_state - 1) : THERMAL_NO_TARGET;

> > -

> > -			/* deactivate a passive thermal instance */

> > -			if ((trip_type == THERMAL_TRIP_PASSIVE ||

> > -			     trip_type == THERMAL_TRIPS_NONE) &&

> > -			     cur_state == THERMAL_NO_TARGET)

> > -				tz->passive--;

> > -			instance->target = cur_state;

> > -			cdev->updated = false; /* cooling device needs

> update */

> > -		}

> > -	}

> > -

> > -	return;

> > -}

> > -/**

> > - * thermal_zone_device_update - force an update of a thermal zone's

> state

> > - * @ttz:	the thermal zone to update

> > - */

> > -

> > -void thermal_zone_device_update(struct thermal_zone_device *tz)

> > -{

> > -	int count, ret = 0;

> > -	long temp, trip_temp;

> > -	enum thermal_trip_type trip_type;

> > -

> > -	mutex_lock(&tz->lock);

> > -

> > -	if (tz->ops->get_temp(tz, &temp)) {

> > -		/* get_temp failed - retry it later */

> > -		pr_warn("failed to read out thermal zone %d\n", tz->id);

> > -		goto leave;

> > -	}

> > -

> > -	tz->last_temperature = tz->temperature;

> > -	tz->temperature = temp;

> > -

> > -	for (count = 0; count < tz->trips; count++) {

> > -		tz->ops->get_trip_type(tz, count, &trip_type);

> > -		tz->ops->get_trip_temp(tz, count, &trip_temp);

> > -

> > -		switch (trip_type) {

> > -		case THERMAL_TRIP_CRITICAL:

> > -			if (temp >= trip_temp) {

> > -				if (tz->ops->notify)

> > -					ret = tz->ops->notify(tz, count,

> > -							      trip_type);

> > -				if (!ret) {

> > -					pr_emerg("Critical temperature

> reached (%ld C), shutting down\n",

> > -						 temp/1000);

> > -					orderly_poweroff(true);

> > -				}

> > -			}

> > -			break;

> > -		case THERMAL_TRIP_HOT:

> > -			if (temp >= trip_temp)

> > -				if (tz->ops->notify)

> > -					tz->ops->notify(tz, count, trip_type);

> > -			break;

> > -		case THERMAL_TRIP_ACTIVE:

> > -			thermal_zone_trip_update(tz, count, temp);

> > -			break;

> > -		case THERMAL_TRIP_PASSIVE:

> > -			if (temp >= trip_temp || tz->passive)

> > -				thermal_zone_trip_update(tz, count, temp);

> > -			break;

> > -		}

> > -	}

> > -

> > -	if (tz->forced_passive)

> > -		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE,

> temp);

> > -	thermal_zone_do_update(tz);

> > -

> > -leave:

> > -	if (tz->passive)

> > -		thermal_zone_device_set_polling(tz, tz->passive_delay);

> > -	else if (tz->polling_delay)

> > -		thermal_zone_device_set_polling(tz, tz->polling_delay);

> > -	else

> > -		thermal_zone_device_set_polling(tz, 0);

> > -	mutex_unlock(&tz->lock);

> > -}

> > -EXPORT_SYMBOL(thermal_zone_device_update);

> > -

> >  /**

> >   * create_trip_attrs - create attributes for trip points

> >   * @tz:		the thermal zone device

>
Zhang Rui Sept. 11, 2012, 12:24 a.m. UTC | #3
On ?, 2012-09-10 at 02:56 -0600, R, Durgadoss wrote:
> Hi Rui,
> 
> > -----Original Message-----
> > From: Zhang, Rui
> > Sent: Monday, September 10, 2012 2:14 PM
> > To: R, Durgadoss
> > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org; eduardo.valentin@ti.com
> > Subject: Re: [PATCHv3 13/15] Thermal: Remove throttling logic out of
> > thermal_sys.c
> [cut.]
> 
> > > +
> > > +static void handle_non_critical_trips(struct thermal_zone_device *tz,
> > > +			int trip, enum thermal_trip_type trip_type)
> > > +{
> > > +	tz->governor->throttle(tz, trip);
> > > +}
> > here is the problem, we must make sure every registered thermal zone
> > have a governor when it is running, right?
> 
> Yes, agree with you. Had some thoughts here, but wanted to get your opinion
> before I implemented them.
> 
> 1. We can make the default governor as 'user space', and make it load inside
> thermal_sys.c (so that every zone will always have a default governor)
> 
No, the default governor should be step wise so that it behaves the same
as before. if we use userspace as default governor, most of the thermal
driver will stop working with this patch set.

IMO, we should make all of the governors configurable, but at least one
of them must be selected as the default governor, that's why we need
something below.

choice
        prompt "Default thermal governor"
        default THERMAL_DEFAULT_GOV_STEP_WISE
        help
          This option sets which thermal governor shall be loaded at
          startup.

thanks,
rui

> 2. All other governors, that are implemented in a separate .c file can be
> optional i.e. left to the user to select/deselect.
> 
> IMO, this will make our implementation easier and cleaner.
> What do you think ?
> 
> Thanks,
> Durga
> 
> > 
> > then the default governor must always be built in.
> > We can have a Kconfig option for step_wise, but we should not make it
> > configurable by users.
> > or we can use prompt to get the default governor at build time. say
> > 
> > choice
> >         prompt "Default thermal governor"
> >         default THERMAL_DEFAULT_GOV_STEP_WISE
> >         help
> >           This option sets which thermal governor shall be loaded at
> >           startup.
> > 
> > config THERMAL_DEFAULT_GOV_STEP_WISE
> >         bool "step-wise"
> >         select THERMAL_GOV_STEP_WISE
> >         help
> >           Use the thermal governor 'step-wise' as default.blabla
> > 
> > 
> > thanks,
> > rui
> > 
> > > +
> > > +static void handle_critical_trips(struct thermal_zone_device *tz,
> > > +				int trip, enum thermal_trip_type trip_type)
> > > +{
> > > +	long trip_temp;
> > > +
> > > +	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> > > +
> > > +	/* If we have not crossed the trip_temp, we do not care. */
> > > +	if (tz->temperature < trip_temp)
> > > +		return;
> > > +
> > > +	if (tz->ops->notify)
> > > +		tz->ops->notify(tz, trip, trip_type);
> > > +
> > > +	if (trip_type == THERMAL_TRIP_CRITICAL) {
> > > +		pr_emerg("Critical temperature reached(%d C),shutting
> > down\n",
> > > +			 tz->temperature / 1000);
> > > +		orderly_poweroff(true);
> > > +	}
> > > +}
> > > +
> > > +static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
> > > +{
> > > +	enum thermal_trip_type type;
> > > +
> > > +	tz->ops->get_trip_type(tz, trip, &type);
> > > +
> > > +	if (type == THERMAL_TRIP_CRITICAL || type ==
> > THERMAL_TRIP_HOT)
> > > +		handle_critical_trips(tz, trip, type);
> > > +	else
> > > +		handle_non_critical_trips(tz, trip, type);
> > > +	/*
> > > +	 * Alright, we handled this trip successfully.
> > > +	 * So, start monitoring again.
> > > +	 */
> > > +	monitor_thermal_zone(tz);
> > > +}
> > > +
> > > +static void update_temperature(struct thermal_zone_device *tz)
> > > +{
> > > +	long temp;
> > > +	int ret;
> > > +
> > > +	mutex_lock(&tz->lock);
> > > +
> > > +	ret = tz->ops->get_temp(tz, &temp);
> > > +	if (ret) {
> > > +		pr_warn("failed to read out thermal zone %d\n", tz->id);
> > > +		return;
> > > +	}
> > > +
> > > +	tz->last_temperature = tz->temperature;
> > > +	tz->temperature = temp;
> > > +
> > > +	mutex_unlock(&tz->lock);
> > > +}
> > > +
> > > +void thermal_zone_device_update(struct thermal_zone_device *tz)
> > > +{
> > > +	int count;
> > > +
> > > +	update_temperature(tz);
> > > +
> > > +	for (count = 0; count < tz->trips; count++)
> > > +		handle_thermal_trip(tz, count);
> > > +}
> > > +EXPORT_SYMBOL(thermal_zone_device_update);
> > > +
> > > +static void thermal_zone_device_check(struct work_struct *work)
> > > +{
> > > +	struct thermal_zone_device *tz = container_of(work, struct
> > > +						      thermal_zone_device,
> > > +						      poll_queue.work);
> > > +	thermal_zone_device_update(tz);
> > > +}
> > > +
> > >  /* sys I/F for thermal zone */
> > >
> > >  #define to_thermal_zone(_dev) \
> > > @@ -936,30 +1048,6 @@ thermal_remove_hwmon_sysfs(struct
> > thermal_zone_device *tz)
> > >  }
> > >  #endif
> > >
> > > -static void thermal_zone_device_set_polling(struct thermal_zone_device
> > *tz,
> > > -					    int delay)
> > > -{
> > > -	cancel_delayed_work(&(tz->poll_queue));
> > > -
> > > -	if (!delay)
> > > -		return;
> > > -
> > > -	if (delay > 1000)
> > > -		queue_delayed_work(system_freezable_wq, &(tz-
> > >poll_queue),
> > > -				      round_jiffies(msecs_to_jiffies(delay)));
> > > -	else
> > > -		queue_delayed_work(system_freezable_wq, &(tz-
> > >poll_queue),
> > > -				      msecs_to_jiffies(delay));
> > > -}
> > > -
> > > -static void thermal_zone_device_check(struct work_struct *work)
> > > -{
> > > -	struct thermal_zone_device *tz = container_of(work, struct
> > > -						      thermal_zone_device,
> > > -						      poll_queue.work);
> > > -	thermal_zone_device_update(tz);
> > > -}
> > > -
> > >  /**
> > >   * thermal_zone_bind_cooling_device - bind a cooling device to a thermal
> > zone
> > >   * @tz:		thermal zone device
> > > @@ -1283,183 +1371,6 @@ void thermal_cdev_update(struct
> > thermal_cooling_device *cdev)
> > >  }
> > >  EXPORT_SYMBOL(thermal_cdev_update);
> > >
> > > -static void thermal_zone_do_update(struct thermal_zone_device *tz)
> > > -{
> > > -	struct thermal_instance *instance;
> > > -
> > > -	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
> > > -		thermal_cdev_update(instance->cdev);
> > > -}
> > > -
> > > -/*
> > > - * Cooling algorithm for both active and passive cooling
> > > - *
> > > - * 1. if the temperature is higher than a trip point,
> > > - *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
> > > - *       state for this trip point
> > > - *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
> > > - *       state for this trip point
> > > - *
> > > - * 2. if the temperature is lower than a trip point, use lower
> > > - *    cooling state for this trip point
> > > - *
> > > - * Note that this behaves the same as the previous passive cooling
> > > - * algorithm.
> > > - */
> > > -
> > > -static void thermal_zone_trip_update(struct thermal_zone_device *tz,
> > > -				     int trip, long temp)
> > > -{
> > > -	struct thermal_instance *instance;
> > > -	struct thermal_cooling_device *cdev = NULL;
> > > -	unsigned long cur_state, max_state;
> > > -	long trip_temp;
> > > -	enum thermal_trip_type trip_type;
> > > -	enum thermal_trend trend;
> > > -
> > > -	if (trip == THERMAL_TRIPS_NONE) {
> > > -		trip_temp = tz->forced_passive;
> > > -		trip_type = THERMAL_TRIPS_NONE;
> > > -	} else {
> > > -		tz->ops->get_trip_temp(tz, trip, &trip_temp);
> > > -		tz->ops->get_trip_type(tz, trip, &trip_type);
> > > -	}
> > > -
> > > -	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> > > -		/*
> > > -		 * compare the current temperature and previous
> > temperature
> > > -		 * to get the thermal trend, if no special requirement
> > > -		 */
> > > -		if (tz->temperature > tz->last_temperature)
> > > -			trend = THERMAL_TREND_RAISING;
> > > -		else if (tz->temperature < tz->last_temperature)
> > > -			trend = THERMAL_TREND_DROPPING;
> > > -		else
> > > -			trend = THERMAL_TREND_STABLE;
> > > -	}
> > > -
> > > -	if (temp >= trip_temp) {
> > > -		list_for_each_entry(instance, &tz->thermal_instances,
> > tz_node) {
> > > -			if (instance->trip != trip)
> > > -				continue;
> > > -
> > > -			cdev = instance->cdev;
> > > -
> > > -			cdev->ops->get_cur_state(cdev, &cur_state);
> > > -			cdev->ops->get_max_state(cdev, &max_state);
> > > -
> > > -			if (trend == THERMAL_TREND_RAISING) {
> > > -				cur_state = cur_state < instance->upper ?
> > > -					    (cur_state + 1) : instance->upper;
> > > -			} else if (trend == THERMAL_TREND_DROPPING) {
> > > -				cur_state = cur_state > instance->lower ?
> > > -				    (cur_state - 1) : instance->lower;
> > > -			}
> > > -
> > > -			/* activate a passive thermal instance */
> > > -			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> > > -			     trip_type == THERMAL_TRIPS_NONE) &&
> > > -			     instance->target == THERMAL_NO_TARGET)
> > > -				tz->passive++;
> > > -
> > > -			instance->target = cur_state;
> > > -			cdev->updated = false; /* cooling device needs
> > update */
> > > -		}
> > > -	} else {	/* below trip */
> > > -		list_for_each_entry(instance, &tz->thermal_instances,
> > tz_node) {
> > > -			if (instance->trip != trip)
> > > -				continue;
> > > -
> > > -			/* Do not use the inactive thermal instance */
> > > -			if (instance->target == THERMAL_NO_TARGET)
> > > -				continue;
> > > -			cdev = instance->cdev;
> > > -			cdev->ops->get_cur_state(cdev, &cur_state);
> > > -
> > > -			cur_state = cur_state > instance->lower ?
> > > -				    (cur_state - 1) : THERMAL_NO_TARGET;
> > > -
> > > -			/* deactivate a passive thermal instance */
> > > -			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> > > -			     trip_type == THERMAL_TRIPS_NONE) &&
> > > -			     cur_state == THERMAL_NO_TARGET)
> > > -				tz->passive--;
> > > -			instance->target = cur_state;
> > > -			cdev->updated = false; /* cooling device needs
> > update */
> > > -		}
> > > -	}
> > > -
> > > -	return;
> > > -}
> > > -/**
> > > - * thermal_zone_device_update - force an update of a thermal zone's
> > state
> > > - * @ttz:	the thermal zone to update
> > > - */
> > > -
> > > -void thermal_zone_device_update(struct thermal_zone_device *tz)
> > > -{
> > > -	int count, ret = 0;
> > > -	long temp, trip_temp;
> > > -	enum thermal_trip_type trip_type;
> > > -
> > > -	mutex_lock(&tz->lock);
> > > -
> > > -	if (tz->ops->get_temp(tz, &temp)) {
> > > -		/* get_temp failed - retry it later */
> > > -		pr_warn("failed to read out thermal zone %d\n", tz->id);
> > > -		goto leave;
> > > -	}
> > > -
> > > -	tz->last_temperature = tz->temperature;
> > > -	tz->temperature = temp;
> > > -
> > > -	for (count = 0; count < tz->trips; count++) {
> > > -		tz->ops->get_trip_type(tz, count, &trip_type);
> > > -		tz->ops->get_trip_temp(tz, count, &trip_temp);
> > > -
> > > -		switch (trip_type) {
> > > -		case THERMAL_TRIP_CRITICAL:
> > > -			if (temp >= trip_temp) {
> > > -				if (tz->ops->notify)
> > > -					ret = tz->ops->notify(tz, count,
> > > -							      trip_type);
> > > -				if (!ret) {
> > > -					pr_emerg("Critical temperature
> > reached (%ld C), shutting down\n",
> > > -						 temp/1000);
> > > -					orderly_poweroff(true);
> > > -				}
> > > -			}
> > > -			break;
> > > -		case THERMAL_TRIP_HOT:
> > > -			if (temp >= trip_temp)
> > > -				if (tz->ops->notify)
> > > -					tz->ops->notify(tz, count, trip_type);
> > > -			break;
> > > -		case THERMAL_TRIP_ACTIVE:
> > > -			thermal_zone_trip_update(tz, count, temp);
> > > -			break;
> > > -		case THERMAL_TRIP_PASSIVE:
> > > -			if (temp >= trip_temp || tz->passive)
> > > -				thermal_zone_trip_update(tz, count, temp);
> > > -			break;
> > > -		}
> > > -	}
> > > -
> > > -	if (tz->forced_passive)
> > > -		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE,
> > temp);
> > > -	thermal_zone_do_update(tz);
> > > -
> > > -leave:
> > > -	if (tz->passive)
> > > -		thermal_zone_device_set_polling(tz, tz->passive_delay);
> > > -	else if (tz->polling_delay)
> > > -		thermal_zone_device_set_polling(tz, tz->polling_delay);
> > > -	else
> > > -		thermal_zone_device_set_polling(tz, 0);
> > > -	mutex_unlock(&tz->lock);
> > > -}
> > > -EXPORT_SYMBOL(thermal_zone_device_update);
> > > -
> > >  /**
> > >   * create_trip_attrs - create attributes for trip points
> > >   * @tz:		the thermal zone device
> > 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
durgadoss.r@intel.com Sept. 11, 2012, 3:05 a.m. UTC | #4
Hi Rui,

> On ?, 2012-09-10 at 02:56 -0600, R, Durgadoss wrote:

> > Hi Rui,

> >

> > > -----Original Message-----

> > > From: Zhang, Rui

> > > Sent: Monday, September 10, 2012 2:14 PM

> > > To: R, Durgadoss

> > > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org;

> eduardo.valentin@ti.com

> > > Subject: Re: [PATCHv3 13/15] Thermal: Remove throttling logic out of

> > > thermal_sys.c

> > [cut.]

> >

> > > > +

> > > > +static void handle_non_critical_trips(struct thermal_zone_device *tz,

> > > > +			int trip, enum thermal_trip_type trip_type)

> > > > +{

> > > > +	tz->governor->throttle(tz, trip);

> > > > +}

> > > here is the problem, we must make sure every registered thermal zone

> > > have a governor when it is running, right?

> >

> > Yes, agree with you. Had some thoughts here, but wanted to get your

> opinion

> > before I implemented them.

> >

> > 1. We can make the default governor as 'user space', and make it load

> inside

> > thermal_sys.c (so that every zone will always have a default governor)

> >

> No, the default governor should be step wise so that it behaves the same

> as before. if we use userspace as default governor, most of the thermal

> driver will stop working with this patch set.


yes, I understand. Shall make step_wise default, and always loaded.

For user space, should we move it to a new .c file, and make it like
other governors or can we keep it as it is ?

Thanks,
Durga

> 

> IMO, we should make all of the governors configurable, but at least one

> of them must be selected as the default governor, that's why we need

> something below.

> 

> choice

>         prompt "Default thermal governor"

>         default THERMAL_DEFAULT_GOV_STEP_WISE

>         help

>           This option sets which thermal governor shall be loaded at

>           startup.

> 

> thanks,

> rui

> 

> > 2. All other governors, that are implemented in a separate .c file can be

> > optional i.e. left to the user to select/deselect.

> >

> > IMO, this will make our implementation easier and cleaner.

> > What do you think ?

> >

> > Thanks,

> > Durga

> >

> > >

> > > then the default governor must always be built in.

> > > We can have a Kconfig option for step_wise, but we should not make it

> > > configurable by users.

> > > or we can use prompt to get the default governor at build time. say

> > >

> > > choice

> > >         prompt "Default thermal governor"

> > >         default THERMAL_DEFAULT_GOV_STEP_WISE

> > >         help

> > >           This option sets which thermal governor shall be loaded at

> > >           startup.

> > >

> > > config THERMAL_DEFAULT_GOV_STEP_WISE

> > >         bool "step-wise"

> > >         select THERMAL_GOV_STEP_WISE

> > >         help

> > >           Use the thermal governor 'step-wise' as default.blabla

> > >

> > >

> > > thanks,

> > > rui
Zhang Rui Sept. 11, 2012, 3:20 a.m. UTC | #5
On ?, 2012-09-10 at 21:05 -0600, R, Durgadoss wrote:
> Hi Rui,
> 
> > On ?, 2012-09-10 at 02:56 -0600, R, Durgadoss wrote:
> > > Hi Rui,
> > >
> > > > -----Original Message-----
> > > > From: Zhang, Rui
> > > > Sent: Monday, September 10, 2012 2:14 PM
> > > > To: R, Durgadoss
> > > > Cc: lenb@kernel.org; linux-acpi@vger.kernel.org;
> > eduardo.valentin@ti.com
> > > > Subject: Re: [PATCHv3 13/15] Thermal: Remove throttling logic out of
> > > > thermal_sys.c
> > > [cut.]
> > >
> > > > > +
> > > > > +static void handle_non_critical_trips(struct thermal_zone_device *tz,
> > > > > +			int trip, enum thermal_trip_type trip_type)
> > > > > +{
> > > > > +	tz->governor->throttle(tz, trip);
> > > > > +}
> > > > here is the problem, we must make sure every registered thermal zone
> > > > have a governor when it is running, right?
> > >
> > > Yes, agree with you. Had some thoughts here, but wanted to get your
> > opinion
> > > before I implemented them.
> > >
> > > 1. We can make the default governor as 'user space', and make it load
> > inside
> > > thermal_sys.c (so that every zone will always have a default governor)
> > >
> > No, the default governor should be step wise so that it behaves the same
> > as before. if we use userspace as default governor, most of the thermal
> > driver will stop working with this patch set.
> 
> yes, I understand. Shall make step_wise default, and always loaded.
> 
we can always make step-wise default, or we can ask users to select one
as default and load it.

> For user space, should we move it to a new .c file, and make it like
> other governors or can we keep it as it is ?
> 
a new .c file for userspace governor.

> Thanks,
> Durga
> 
> > 
> > IMO, we should make all of the governors configurable, but at least one
> > of them must be selected as the default governor, that's why we need
> > something below.
> > 
> > choice
> >         prompt "Default thermal governor"
> >         default THERMAL_DEFAULT_GOV_STEP_WISE
> >         help
> >           This option sets which thermal governor shall be loaded at
> >           startup.
> > 
> > thanks,
> > rui
> > 
> > > 2. All other governors, that are implemented in a separate .c file can be
> > > optional i.e. left to the user to select/deselect.
> > >
> > > IMO, this will make our implementation easier and cleaner.
> > > What do you think ?
> > >
> > > Thanks,
> > > Durga
> > >
> > > >
> > > > then the default governor must always be built in.
> > > > We can have a Kconfig option for step_wise, but we should not make it
> > > > configurable by users.
> > > > or we can use prompt to get the default governor at build time. say
> > > >
> > > > choice
> > > >         prompt "Default thermal governor"
> > > >         default THERMAL_DEFAULT_GOV_STEP_WISE
> > > >         help
> > > >           This option sets which thermal governor shall be loaded at
> > > >           startup.
> > > >
> > > > config THERMAL_DEFAULT_GOV_STEP_WISE
> > > >         bool "step-wise"
> > > >         select THERMAL_GOV_STEP_WISE
> > > >         help
> > > >           Use the thermal governor 'step-wise' as default.blabla
> > > >
> > > >
> > > > thanks,
> > > > rui


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
durgadoss.r@intel.com Sept. 11, 2012, 3:39 a.m. UTC | #6
SGkgUnVpLA0KDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogWmhhbmcs
IFJ1aQ0KPiBTZW50OiBUdWVzZGF5LCBTZXB0ZW1iZXIgMTEsIDIwMTIgODo1MSBBTQ0KPiBUbzog
UiwgRHVyZ2Fkb3NzDQo+IENjOiBsZW5iQGtlcm5lbC5vcmc7IGxpbnV4LWFjcGlAdmdlci5rZXJu
ZWwub3JnOyBlZHVhcmRvLnZhbGVudGluQHRpLmNvbQ0KPiBTdWJqZWN0OiBSRTogW1BBVENIdjMg
MTMvMTVdIFRoZXJtYWw6IFJlbW92ZSB0aHJvdHRsaW5nIGxvZ2ljIG91dCBvZg0KPiB0aGVybWFs
X3N5cy5jDQo+IA0KPiBPbiDkuIAsIDIwMTItMDktMTAgYXQgMjE6MDUgLTA2MDAsIFIsIER1cmdh
ZG9zcyB3cm90ZToNCj4gPiBIaSBSdWksDQo+ID4NCj4gPiA+IE9uIOS4gCwgMjAxMi0wOS0xMCBh
dCAwMjo1NiAtMDYwMCwgUiwgRHVyZ2Fkb3NzIHdyb3RlOg0KPiA+ID4gPiBIaSBSdWksDQo+ID4g
PiA+DQo+ID4gPiA+ID4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPiA+ID4gPiBGcm9t
OiBaaGFuZywgUnVpDQo+ID4gPiA+ID4gU2VudDogTW9uZGF5LCBTZXB0ZW1iZXIgMTAsIDIwMTIg
MjoxNCBQTQ0KPiA+ID4gPiA+IFRvOiBSLCBEdXJnYWRvc3MNCj4gPiA+ID4gPiBDYzogbGVuYkBr
ZXJuZWwub3JnOyBsaW51eC1hY3BpQHZnZXIua2VybmVsLm9yZzsNCj4gPiA+IGVkdWFyZG8udmFs
ZW50aW5AdGkuY29tDQo+ID4gPiA+ID4gU3ViamVjdDogUmU6IFtQQVRDSHYzIDEzLzE1XSBUaGVy
bWFsOiBSZW1vdmUgdGhyb3R0bGluZyBsb2dpYyBvdXQgb2YNCj4gPiA+ID4gPiB0aGVybWFsX3N5
cy5jDQo+ID4gPiA+IFtjdXQuXQ0KPiA+ID4gPg0KPiA+ID4gPiA+ID4gKw0KPiA+ID4gPiA+ID4g
K3N0YXRpYyB2b2lkIGhhbmRsZV9ub25fY3JpdGljYWxfdHJpcHMoc3RydWN0IHRoZXJtYWxfem9u
ZV9kZXZpY2UNCj4gKnR6LA0KPiA+ID4gPiA+ID4gKwkJCWludCB0cmlwLCBlbnVtIHRoZXJtYWxf
dHJpcF90eXBlIHRyaXBfdHlwZSkNCj4gPiA+ID4gPiA+ICt7DQo+ID4gPiA+ID4gPiArCXR6LT5n
b3Zlcm5vci0+dGhyb3R0bGUodHosIHRyaXApOw0KPiA+ID4gPiA+ID4gK30NCj4gPiA+ID4gPiBo
ZXJlIGlzIHRoZSBwcm9ibGVtLCB3ZSBtdXN0IG1ha2Ugc3VyZSBldmVyeSByZWdpc3RlcmVkIHRo
ZXJtYWwNCj4gem9uZQ0KPiA+ID4gPiA+IGhhdmUgYSBnb3Zlcm5vciB3aGVuIGl0IGlzIHJ1bm5p
bmcsIHJpZ2h0Pw0KPiA+ID4gPg0KPiA+ID4gPiBZZXMsIGFncmVlIHdpdGggeW91LiBIYWQgc29t
ZSB0aG91Z2h0cyBoZXJlLCBidXQgd2FudGVkIHRvIGdldCB5b3VyDQo+ID4gPiBvcGluaW9uDQo+
ID4gPiA+IGJlZm9yZSBJIGltcGxlbWVudGVkIHRoZW0uDQo+ID4gPiA+DQo+ID4gPiA+IDEuIFdl
IGNhbiBtYWtlIHRoZSBkZWZhdWx0IGdvdmVybm9yIGFzICd1c2VyIHNwYWNlJywgYW5kIG1ha2Ug
aXQgbG9hZA0KPiA+ID4gaW5zaWRlDQo+ID4gPiA+IHRoZXJtYWxfc3lzLmMgKHNvIHRoYXQgZXZl
cnkgem9uZSB3aWxsIGFsd2F5cyBoYXZlIGEgZGVmYXVsdCBnb3Zlcm5vcikNCj4gPiA+ID4NCj4g
PiA+IE5vLCB0aGUgZGVmYXVsdCBnb3Zlcm5vciBzaG91bGQgYmUgc3RlcCB3aXNlIHNvIHRoYXQg
aXQgYmVoYXZlcyB0aGUgc2FtZQ0KPiA+ID4gYXMgYmVmb3JlLiBpZiB3ZSB1c2UgdXNlcnNwYWNl
IGFzIGRlZmF1bHQgZ292ZXJub3IsIG1vc3Qgb2YgdGhlIHRoZXJtYWwNCj4gPiA+IGRyaXZlciB3
aWxsIHN0b3Agd29ya2luZyB3aXRoIHRoaXMgcGF0Y2ggc2V0Lg0KPiA+DQo+ID4geWVzLCBJIHVu
ZGVyc3RhbmQuIFNoYWxsIG1ha2Ugc3RlcF93aXNlIGRlZmF1bHQsIGFuZCBhbHdheXMgbG9hZGVk
Lg0KPiA+DQo+IHdlIGNhbiBhbHdheXMgbWFrZSBzdGVwLXdpc2UgZGVmYXVsdCwgb3Igd2UgY2Fu
IGFzayB1c2VycyB0byBzZWxlY3Qgb25lDQo+IGFzIGRlZmF1bHQgYW5kIGxvYWQgaXQuDQoNCldp
bGwgYWx3YXlzIHN0ZXBfd2lzZSBkZWZhdWx0LiBUaGF0IHdpbGwgZXhhY3RseSBtaW1pYyB0aGUg
b2xkIGJlaGF2aW9yLg0Kd2lsbCBhbHNvIGNyZWF0ZSBhIG5ldyBmaWxlIGZvciB1c2VyIHNwYWNl
IGdvdmVybm9yLg0KDQpUaGFua3MsDQpEdXJnYQ0K
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 93672aa..086c1c9 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -315,6 +315,118 @@  exit:
 	mutex_unlock(&thermal_list_lock);
 }
 
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+					    int delay)
+{
+	cancel_delayed_work(&(tz->poll_queue));
+
+	if (!delay)
+		return;
+
+	if (delay > 1000)
+		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
+				      round_jiffies(msecs_to_jiffies(delay)));
+	else
+		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
+				      msecs_to_jiffies(delay));
+}
+
+static void monitor_thermal_zone(struct thermal_zone_device *tz)
+{
+	mutex_lock(&tz->lock);
+
+	if (tz->passive)
+		thermal_zone_device_set_polling(tz, tz->passive_delay);
+	else if (tz->polling_delay)
+		thermal_zone_device_set_polling(tz, tz->polling_delay);
+	else
+		thermal_zone_device_set_polling(tz, 0);
+
+	mutex_unlock(&tz->lock);
+}
+
+static void handle_non_critical_trips(struct thermal_zone_device *tz,
+			int trip, enum thermal_trip_type trip_type)
+{
+	tz->governor->throttle(tz, trip);
+}
+
+static void handle_critical_trips(struct thermal_zone_device *tz,
+				int trip, enum thermal_trip_type trip_type)
+{
+	long trip_temp;
+
+	tz->ops->get_trip_temp(tz, trip, &trip_temp);
+
+	/* If we have not crossed the trip_temp, we do not care. */
+	if (tz->temperature < trip_temp)
+		return;
+
+	if (tz->ops->notify)
+		tz->ops->notify(tz, trip, trip_type);
+
+	if (trip_type == THERMAL_TRIP_CRITICAL) {
+		pr_emerg("Critical temperature reached(%d C),shutting down\n",
+			 tz->temperature / 1000);
+		orderly_poweroff(true);
+	}
+}
+
+static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
+{
+	enum thermal_trip_type type;
+
+	tz->ops->get_trip_type(tz, trip, &type);
+
+	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
+		handle_critical_trips(tz, trip, type);
+	else
+		handle_non_critical_trips(tz, trip, type);
+	/*
+	 * Alright, we handled this trip successfully.
+	 * So, start monitoring again.
+	 */
+	monitor_thermal_zone(tz);
+}
+
+static void update_temperature(struct thermal_zone_device *tz)
+{
+	long temp;
+	int ret;
+
+	mutex_lock(&tz->lock);
+
+	ret = tz->ops->get_temp(tz, &temp);
+	if (ret) {
+		pr_warn("failed to read out thermal zone %d\n", tz->id);
+		return;
+	}
+
+	tz->last_temperature = tz->temperature;
+	tz->temperature = temp;
+
+	mutex_unlock(&tz->lock);
+}
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+	int count;
+
+	update_temperature(tz);
+
+	for (count = 0; count < tz->trips; count++)
+		handle_thermal_trip(tz, count);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+	struct thermal_zone_device *tz = container_of(work, struct
+						      thermal_zone_device,
+						      poll_queue.work);
+	thermal_zone_device_update(tz);
+}
+
 /* sys I/F for thermal zone */
 
 #define to_thermal_zone(_dev) \
@@ -936,30 +1048,6 @@  thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
 }
 #endif
 
-static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
-					    int delay)
-{
-	cancel_delayed_work(&(tz->poll_queue));
-
-	if (!delay)
-		return;
-
-	if (delay > 1000)
-		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
-				      round_jiffies(msecs_to_jiffies(delay)));
-	else
-		queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
-				      msecs_to_jiffies(delay));
-}
-
-static void thermal_zone_device_check(struct work_struct *work)
-{
-	struct thermal_zone_device *tz = container_of(work, struct
-						      thermal_zone_device,
-						      poll_queue.work);
-	thermal_zone_device_update(tz);
-}
-
 /**
  * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
  * @tz:		thermal zone device
@@ -1283,183 +1371,6 @@  void thermal_cdev_update(struct thermal_cooling_device *cdev)
 }
 EXPORT_SYMBOL(thermal_cdev_update);
 
-static void thermal_zone_do_update(struct thermal_zone_device *tz)
-{
-	struct thermal_instance *instance;
-
-	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
-		thermal_cdev_update(instance->cdev);
-}
-
-/*
- * Cooling algorithm for both active and passive cooling
- *
- * 1. if the temperature is higher than a trip point,
- *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
- *       state for this trip point
- *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
- *       state for this trip point
- *
- * 2. if the temperature is lower than a trip point, use lower
- *    cooling state for this trip point
- *
- * Note that this behaves the same as the previous passive cooling
- * algorithm.
- */
-
-static void thermal_zone_trip_update(struct thermal_zone_device *tz,
-				     int trip, long temp)
-{
-	struct thermal_instance *instance;
-	struct thermal_cooling_device *cdev = NULL;
-	unsigned long cur_state, max_state;
-	long trip_temp;
-	enum thermal_trip_type trip_type;
-	enum thermal_trend trend;
-
-	if (trip == THERMAL_TRIPS_NONE) {
-		trip_temp = tz->forced_passive;
-		trip_type = THERMAL_TRIPS_NONE;
-	} else {
-		tz->ops->get_trip_temp(tz, trip, &trip_temp);
-		tz->ops->get_trip_type(tz, trip, &trip_type);
-	}
-
-	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
-		/*
-		 * compare the current temperature and previous temperature
-		 * to get the thermal trend, if no special requirement
-		 */
-		if (tz->temperature > tz->last_temperature)
-			trend = THERMAL_TREND_RAISING;
-		else if (tz->temperature < tz->last_temperature)
-			trend = THERMAL_TREND_DROPPING;
-		else
-			trend = THERMAL_TREND_STABLE;
-	}
-
-	if (temp >= trip_temp) {
-		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-			if (instance->trip != trip)
-				continue;
-
-			cdev = instance->cdev;
-
-			cdev->ops->get_cur_state(cdev, &cur_state);
-			cdev->ops->get_max_state(cdev, &max_state);
-
-			if (trend == THERMAL_TREND_RAISING) {
-				cur_state = cur_state < instance->upper ?
-					    (cur_state + 1) : instance->upper;
-			} else if (trend == THERMAL_TREND_DROPPING) {
-				cur_state = cur_state > instance->lower ?
-				    (cur_state - 1) : instance->lower;
-			}
-
-			/* activate a passive thermal instance */
-			if ((trip_type == THERMAL_TRIP_PASSIVE ||
-			     trip_type == THERMAL_TRIPS_NONE) &&
-			     instance->target == THERMAL_NO_TARGET)
-				tz->passive++;
-
-			instance->target = cur_state;
-			cdev->updated = false; /* cooling device needs update */
-		}
-	} else {	/* below trip */
-		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-			if (instance->trip != trip)
-				continue;
-
-			/* Do not use the inactive thermal instance */
-			if (instance->target == THERMAL_NO_TARGET)
-				continue;
-			cdev = instance->cdev;
-			cdev->ops->get_cur_state(cdev, &cur_state);
-
-			cur_state = cur_state > instance->lower ?
-				    (cur_state - 1) : THERMAL_NO_TARGET;
-
-			/* deactivate a passive thermal instance */
-			if ((trip_type == THERMAL_TRIP_PASSIVE ||
-			     trip_type == THERMAL_TRIPS_NONE) &&
-			     cur_state == THERMAL_NO_TARGET)
-				tz->passive--;
-			instance->target = cur_state;
-			cdev->updated = false; /* cooling device needs update */
-		}
-	}
-
-	return;
-}
-/**
- * thermal_zone_device_update - force an update of a thermal zone's state
- * @ttz:	the thermal zone to update
- */
-
-void thermal_zone_device_update(struct thermal_zone_device *tz)
-{
-	int count, ret = 0;
-	long temp, trip_temp;
-	enum thermal_trip_type trip_type;
-
-	mutex_lock(&tz->lock);
-
-	if (tz->ops->get_temp(tz, &temp)) {
-		/* get_temp failed - retry it later */
-		pr_warn("failed to read out thermal zone %d\n", tz->id);
-		goto leave;
-	}
-
-	tz->last_temperature = tz->temperature;
-	tz->temperature = temp;
-
-	for (count = 0; count < tz->trips; count++) {
-		tz->ops->get_trip_type(tz, count, &trip_type);
-		tz->ops->get_trip_temp(tz, count, &trip_temp);
-
-		switch (trip_type) {
-		case THERMAL_TRIP_CRITICAL:
-			if (temp >= trip_temp) {
-				if (tz->ops->notify)
-					ret = tz->ops->notify(tz, count,
-							      trip_type);
-				if (!ret) {
-					pr_emerg("Critical temperature reached (%ld C), shutting down\n",
-						 temp/1000);
-					orderly_poweroff(true);
-				}
-			}
-			break;
-		case THERMAL_TRIP_HOT:
-			if (temp >= trip_temp)
-				if (tz->ops->notify)
-					tz->ops->notify(tz, count, trip_type);
-			break;
-		case THERMAL_TRIP_ACTIVE:
-			thermal_zone_trip_update(tz, count, temp);
-			break;
-		case THERMAL_TRIP_PASSIVE:
-			if (temp >= trip_temp || tz->passive)
-				thermal_zone_trip_update(tz, count, temp);
-			break;
-		}
-	}
-
-	if (tz->forced_passive)
-		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
-	thermal_zone_do_update(tz);
-
-leave:
-	if (tz->passive)
-		thermal_zone_device_set_polling(tz, tz->passive_delay);
-	else if (tz->polling_delay)
-		thermal_zone_device_set_polling(tz, tz->polling_delay);
-	else
-		thermal_zone_device_set_polling(tz, 0);
-	mutex_unlock(&tz->lock);
-}
-EXPORT_SYMBOL(thermal_zone_device_update);
-
 /**
  * create_trip_attrs - create attributes for trip points
  * @tz:		the thermal zone device