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@xxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html