X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Fthermal%2Fthermal_core.c;h=d9e525cc9c1ce24bcd9d55dd59730f375b15d552;hb=116ef0fcc9268a876c8d1bbf77d8fa80111fa526;hp=4ca211be4c0f197825be94f70be386af1c2cc33d;hpb=17447717a3266965e257d3eae79d89539ce3ec0a;p=linux-2.6-block.git diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 4ca211be4c0f..d9e525cc9c1c 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -426,7 +426,7 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, static void handle_critical_trips(struct thermal_zone_device *tz, int trip, enum thermal_trip_type trip_type) { - long trip_temp; + int trip_temp; tz->ops->get_trip_temp(tz, trip, &trip_temp); @@ -465,7 +465,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) } /** - * thermal_zone_get_temp() - returns its the temperature of thermal zone + * thermal_zone_get_temp() - returns the temperature of a thermal zone * @tz: a valid pointer to a struct thermal_zone_device * @temp: a valid pointer to where to store the resulting temperature. * @@ -474,14 +474,12 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) * * Return: On success returns 0, an error code otherwise */ -int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp) +int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) { int ret = -EINVAL; -#ifdef CONFIG_THERMAL_EMULATION int count; - unsigned long crit_temp = -1UL; + int crit_temp = INT_MAX; enum thermal_trip_type type; -#endif if (!tz || IS_ERR(tz) || !tz->ops->get_temp) goto exit; @@ -489,25 +487,26 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp) mutex_lock(&tz->lock); ret = tz->ops->get_temp(tz, temp); -#ifdef CONFIG_THERMAL_EMULATION - if (!tz->emul_temperature) - goto skip_emul; - - for (count = 0; count < tz->trips; count++) { - ret = tz->ops->get_trip_type(tz, count, &type); - if (!ret && type == THERMAL_TRIP_CRITICAL) { - ret = tz->ops->get_trip_temp(tz, count, &crit_temp); - break; - } - } - if (ret) - goto skip_emul; + if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) { + for (count = 0; count < tz->trips; count++) { + ret = tz->ops->get_trip_type(tz, count, &type); + if (!ret && type == THERMAL_TRIP_CRITICAL) { + ret = tz->ops->get_trip_temp(tz, count, + &crit_temp); + break; + } + } - if (*temp < crit_temp) - *temp = tz->emul_temperature; -skip_emul: -#endif + /* + * Only allow emulating a temperature when the real temperature + * is below the critical temperature so that the emulation code + * cannot hide critical conditions. + */ + if (!ret && *temp < crit_temp) + *temp = tz->emul_temperature; + } + mutex_unlock(&tz->lock); exit: return ret; @@ -516,8 +515,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp); static void update_temperature(struct thermal_zone_device *tz) { - long temp; - int ret; + int temp, ret; ret = thermal_zone_get_temp(tz, &temp); if (ret) { @@ -577,15 +575,14 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_zone_device *tz = to_thermal_zone(dev); - long temperature; - int ret; + int temperature, ret; ret = thermal_zone_get_temp(tz, &temperature); if (ret) return ret; - return sprintf(buf, "%ld\n", temperature); + return sprintf(buf, "%d\n", temperature); } static ssize_t @@ -689,7 +686,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, { struct thermal_zone_device *tz = to_thermal_zone(dev); int trip, ret; - long temperature; + int temperature; if (!tz->ops->get_trip_temp) return -EPERM; @@ -702,7 +699,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (ret) return ret; - return sprintf(buf, "%ld\n", temperature); + return sprintf(buf, "%d\n", temperature); } static ssize_t @@ -711,7 +708,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, { struct thermal_zone_device *tz = to_thermal_zone(dev); int trip, ret; - unsigned long temperature; + int temperature; if (!tz->ops->set_trip_hyst) return -EPERM; @@ -719,7 +716,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip)) return -EINVAL; - if (kstrtoul(buf, 10, &temperature)) + if (kstrtoint(buf, 10, &temperature)) return -EINVAL; /* @@ -738,7 +735,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, { struct thermal_zone_device *tz = to_thermal_zone(dev); int trip, ret; - unsigned long temperature; + int temperature; if (!tz->ops->get_trip_hyst) return -EPERM; @@ -748,7 +745,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, ret = tz->ops->get_trip_hyst(tz, trip, &temperature); - return ret ? ret : sprintf(buf, "%ld\n", temperature); + return ret ? ret : sprintf(buf, "%d\n", temperature); } static ssize_t @@ -847,7 +844,27 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf) return sprintf(buf, "%s\n", tz->governor->name); } -#ifdef CONFIG_THERMAL_EMULATION +static ssize_t +available_policies_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct thermal_governor *pos; + ssize_t count = 0; + ssize_t size = PAGE_SIZE; + + mutex_lock(&thermal_governor_lock); + + list_for_each_entry(pos, &thermal_governor_list, governor_list) { + size = PAGE_SIZE - count; + count += scnprintf(buf + count, size, "%s ", pos->name); + } + count += scnprintf(buf + count, size, "\n"); + + mutex_unlock(&thermal_governor_lock); + + return count; +} + static ssize_t emul_temp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -873,7 +890,6 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, return ret ? ret : count; } static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store); -#endif/*CONFIG_THERMAL_EMULATION*/ static ssize_t sustainable_power_show(struct device *dev, struct device_attribute *devattr, @@ -996,6 +1012,34 @@ int power_actor_get_max_power(struct thermal_cooling_device *cdev, return cdev->ops->state2power(cdev, tz, 0, max_power); } +/** + * power_actor_get_min_power() - get the mainimum power that a cdev can consume + * @cdev: pointer to &thermal_cooling_device + * @tz: a valid thermal zone device pointer + * @min_power: pointer in which to store the minimum power + * + * Calculate the minimum power consumption in milliwatts that the + * cooling device can currently consume and store it in @min_power. + * + * Return: 0 on success, -EINVAL if @cdev doesn't support the + * power_actor API or -E* on other error. + */ +int power_actor_get_min_power(struct thermal_cooling_device *cdev, + struct thermal_zone_device *tz, u32 *min_power) +{ + unsigned long max_state; + int ret; + + if (!cdev_is_power_actor(cdev)) + return -EINVAL; + + ret = cdev->ops->get_max_state(cdev, &max_state); + if (ret) + return ret; + + return cdev->ops->state2power(cdev, tz, max_state, min_power); +} + /** * power_actor_set_power() - limit the maximum power that a cooling device can consume * @cdev: pointer to &thermal_cooling_device @@ -1032,6 +1076,7 @@ static DEVICE_ATTR(temp, 0444, temp_show, NULL); static DEVICE_ATTR(mode, 0644, mode_show, mode_store); static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store); +static DEVICE_ATTR(available_policies, S_IRUGO, available_policies_show, NULL); /* sys I/F for cooling device */ #define to_cooling_device(_dev) \ @@ -1803,11 +1848,12 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, goto unregister; } -#ifdef CONFIG_THERMAL_EMULATION - result = device_create_file(&tz->device, &dev_attr_emul_temp); - if (result) - goto unregister; -#endif + if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) { + result = device_create_file(&tz->device, &dev_attr_emul_temp); + if (result) + goto unregister; + } + /* Create policy attribute */ result = device_create_file(&tz->device, &dev_attr_policy); if (result) @@ -1818,6 +1864,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, if (result) goto unregister; + /* Create available_policies attribute */ + result = device_create_file(&tz->device, &dev_attr_available_policies); + if (result) + goto unregister; + /* Update 'this' zone's governor information */ mutex_lock(&thermal_governor_lock); @@ -1849,9 +1900,6 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); - if (!tz->ops->get_temp) - thermal_zone_device_set_polling(tz, 0); - thermal_zone_device_update(tz); return tz; @@ -1918,6 +1966,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) if (tz->ops->get_mode) device_remove_file(&tz->device, &dev_attr_mode); device_remove_file(&tz->device, &dev_attr_policy); + device_remove_file(&tz->device, &dev_attr_available_policies); remove_trip_attrs(tz); thermal_set_governor(tz, NULL);