Loading drivers/thermal/thermal_core.c +61 −4 Original line number Diff line number Diff line Loading @@ -1199,6 +1199,25 @@ thermal_cooling_device_max_state_show(struct device *dev, return sprintf(buf, "%ld\n", state); } static ssize_t thermal_cooling_device_min_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_cooling_device *cdev = to_cooling_device(dev); unsigned long state; int ret; if (cdev->ops->get_min_state) ret = cdev->ops->get_min_state(cdev, &state); else ret = -EPERM; if (ret) return ret; return snprintf(buf, PAGE_SIZE, "%lu\n", state); } static ssize_t thermal_cooling_device_cur_state_show(struct device *dev, struct device_attribute *attr, char *buf) Loading Loading @@ -1235,6 +1254,30 @@ thermal_cooling_device_cur_state_store(struct device *dev, return count; } static ssize_t thermal_cooling_device_min_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_cooling_device *cdev = to_cooling_device(dev); long state; int ret = 0; ret = sscanf(buf, "%ld\n", &state); if (ret <= 0) return (ret < 0) ? ret : -EINVAL; if ((long)state < 0) return -EINVAL; cdev->sysfs_min_state_req = state; cdev->updated = false; thermal_cdev_update(cdev); return count; } static struct device_attribute dev_attr_cdev_type = __ATTR(type, 0444, thermal_cooling_device_type_show, NULL); static DEVICE_ATTR(max_state, 0444, Loading @@ -1242,6 +1285,9 @@ static DEVICE_ATTR(max_state, 0444, static DEVICE_ATTR(cur_state, 0644, thermal_cooling_device_cur_state_show, thermal_cooling_device_cur_state_store); static DEVICE_ATTR(min_state, 0644, thermal_cooling_device_min_state_show, thermal_cooling_device_min_state_store); static ssize_t thermal_cooling_device_trip_point_show(struct device *dev, Loading @@ -1262,6 +1308,7 @@ static struct attribute *cooling_device_attrs[] = { &dev_attr_cdev_type.attr, &dev_attr_max_state.attr, &dev_attr_cur_state.attr, &dev_attr_min_state.attr, NULL, }; Loading Loading @@ -1556,6 +1603,7 @@ __thermal_cooling_device_register(struct device_node *np, cdev->device.groups = cooling_device_attr_groups; cdev->devdata = devdata; cdev->sysfs_cur_state_req = 0; cdev->sysfs_min_state_req = ULONG_MAX; dev_set_name(&cdev->device, "cooling_device%d", cdev->id); result = device_register(&cdev->device); if (result) { Loading Loading @@ -1690,7 +1738,7 @@ EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); void thermal_cdev_update(struct thermal_cooling_device *cdev) { struct thermal_instance *instance; unsigned long current_target = 0; unsigned long current_target = 0, min_target = ULONG_MAX; mutex_lock(&cdev->lock); /* cooling device is updated*/ Loading @@ -1701,19 +1749,28 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev) /* Make sure cdev enters the deepest cooling state */ current_target = cdev->sysfs_cur_state_req; min_target = cdev->sysfs_min_state_req; list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) { dev_dbg(&cdev->device, "zone%d->target=%lu\n", instance->tz->id, instance->target); if (instance->target == THERMAL_NO_TARGET) continue; if (instance->tz->governor->min_state_throttle) { if (instance->target < min_target) min_target = instance->target; } else { if (instance->target > current_target) current_target = instance->target; } } cdev->ops->set_cur_state(cdev, current_target); if (cdev->ops->set_min_state) cdev->ops->set_min_state(cdev, min_target); cdev->updated = true; mutex_unlock(&cdev->lock); trace_cdev_update(cdev, current_target); dev_dbg(&cdev->device, "set to state %lu\n", current_target); dev_dbg(&cdev->device, "set to state %lu min state %lu\n", current_target, min_target); } EXPORT_SYMBOL(thermal_cdev_update); Loading include/linux/thermal.h +3 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ struct thermal_cooling_device_ops { int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); int (*set_min_state)(struct thermal_cooling_device *, unsigned long); int (*get_min_state)(struct thermal_cooling_device *, unsigned long *); int (*get_requested_power)(struct thermal_cooling_device *, struct thermal_zone_device *, u32 *); int (*state2power)(struct thermal_cooling_device *, Loading Loading @@ -262,6 +264,7 @@ struct thermal_governor { void (*unbind_from_tz)(struct thermal_zone_device *tz); int (*throttle)(struct thermal_zone_device *tz, int trip); struct list_head governor_list; int min_state_throttle; }; /* Structure that holds binding parameters for a zone */ Loading Loading
drivers/thermal/thermal_core.c +61 −4 Original line number Diff line number Diff line Loading @@ -1199,6 +1199,25 @@ thermal_cooling_device_max_state_show(struct device *dev, return sprintf(buf, "%ld\n", state); } static ssize_t thermal_cooling_device_min_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_cooling_device *cdev = to_cooling_device(dev); unsigned long state; int ret; if (cdev->ops->get_min_state) ret = cdev->ops->get_min_state(cdev, &state); else ret = -EPERM; if (ret) return ret; return snprintf(buf, PAGE_SIZE, "%lu\n", state); } static ssize_t thermal_cooling_device_cur_state_show(struct device *dev, struct device_attribute *attr, char *buf) Loading Loading @@ -1235,6 +1254,30 @@ thermal_cooling_device_cur_state_store(struct device *dev, return count; } static ssize_t thermal_cooling_device_min_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_cooling_device *cdev = to_cooling_device(dev); long state; int ret = 0; ret = sscanf(buf, "%ld\n", &state); if (ret <= 0) return (ret < 0) ? ret : -EINVAL; if ((long)state < 0) return -EINVAL; cdev->sysfs_min_state_req = state; cdev->updated = false; thermal_cdev_update(cdev); return count; } static struct device_attribute dev_attr_cdev_type = __ATTR(type, 0444, thermal_cooling_device_type_show, NULL); static DEVICE_ATTR(max_state, 0444, Loading @@ -1242,6 +1285,9 @@ static DEVICE_ATTR(max_state, 0444, static DEVICE_ATTR(cur_state, 0644, thermal_cooling_device_cur_state_show, thermal_cooling_device_cur_state_store); static DEVICE_ATTR(min_state, 0644, thermal_cooling_device_min_state_show, thermal_cooling_device_min_state_store); static ssize_t thermal_cooling_device_trip_point_show(struct device *dev, Loading @@ -1262,6 +1308,7 @@ static struct attribute *cooling_device_attrs[] = { &dev_attr_cdev_type.attr, &dev_attr_max_state.attr, &dev_attr_cur_state.attr, &dev_attr_min_state.attr, NULL, }; Loading Loading @@ -1556,6 +1603,7 @@ __thermal_cooling_device_register(struct device_node *np, cdev->device.groups = cooling_device_attr_groups; cdev->devdata = devdata; cdev->sysfs_cur_state_req = 0; cdev->sysfs_min_state_req = ULONG_MAX; dev_set_name(&cdev->device, "cooling_device%d", cdev->id); result = device_register(&cdev->device); if (result) { Loading Loading @@ -1690,7 +1738,7 @@ EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); void thermal_cdev_update(struct thermal_cooling_device *cdev) { struct thermal_instance *instance; unsigned long current_target = 0; unsigned long current_target = 0, min_target = ULONG_MAX; mutex_lock(&cdev->lock); /* cooling device is updated*/ Loading @@ -1701,19 +1749,28 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev) /* Make sure cdev enters the deepest cooling state */ current_target = cdev->sysfs_cur_state_req; min_target = cdev->sysfs_min_state_req; list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) { dev_dbg(&cdev->device, "zone%d->target=%lu\n", instance->tz->id, instance->target); if (instance->target == THERMAL_NO_TARGET) continue; if (instance->tz->governor->min_state_throttle) { if (instance->target < min_target) min_target = instance->target; } else { if (instance->target > current_target) current_target = instance->target; } } cdev->ops->set_cur_state(cdev, current_target); if (cdev->ops->set_min_state) cdev->ops->set_min_state(cdev, min_target); cdev->updated = true; mutex_unlock(&cdev->lock); trace_cdev_update(cdev, current_target); dev_dbg(&cdev->device, "set to state %lu\n", current_target); dev_dbg(&cdev->device, "set to state %lu min state %lu\n", current_target, min_target); } EXPORT_SYMBOL(thermal_cdev_update); Loading
include/linux/thermal.h +3 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ struct thermal_cooling_device_ops { int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); int (*set_min_state)(struct thermal_cooling_device *, unsigned long); int (*get_min_state)(struct thermal_cooling_device *, unsigned long *); int (*get_requested_power)(struct thermal_cooling_device *, struct thermal_zone_device *, u32 *); int (*state2power)(struct thermal_cooling_device *, Loading Loading @@ -262,6 +264,7 @@ struct thermal_governor { void (*unbind_from_tz)(struct thermal_zone_device *tz); int (*throttle)(struct thermal_zone_device *tz, int trip); struct list_head governor_list; int min_state_throttle; }; /* Structure that holds binding parameters for a zone */ Loading