diff options
Diffstat (limited to 'drivers/thermal/thermal_core.c')
-rw-r--r-- | drivers/thermal/thermal_core.c | 178 |
1 files changed, 51 insertions, 127 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 566df4522b88..842f678c1c3e 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -22,7 +22,7 @@ #include <linux/suspend.h> #define CREATE_TRACE_POINTS -#include <trace/events/thermal.h> +#include "thermal_trace.h" #include "thermal_core.h" #include "thermal_hwmon.h" @@ -794,68 +794,18 @@ void print_bind_err_msg(struct thermal_zone_device *tz, tz->type, cdev->type, ret); } -static void __bind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev, - unsigned long *limits, - unsigned int weight) -{ - int i, ret; - - for (i = 0; i < tz->num_trips; i++) { - if (mask & (1 << i)) { - unsigned long upper, lower; - - upper = THERMAL_NO_LIMIT; - lower = THERMAL_NO_LIMIT; - if (limits) { - lower = limits[i * 2]; - upper = limits[i * 2 + 1]; - } - ret = thermal_zone_bind_cooling_device(tz, i, cdev, - upper, lower, - weight); - if (ret) - print_bind_err_msg(tz, cdev, ret); - } - } -} - static void bind_cdev(struct thermal_cooling_device *cdev) { - int i, ret; - const struct thermal_zone_params *tzp; + int ret; struct thermal_zone_device *pos = NULL; - mutex_lock(&thermal_list_lock); - list_for_each_entry(pos, &thermal_tz_list, node) { - if (!pos->tzp && !pos->ops->bind) - continue; - if (pos->ops->bind) { ret = pos->ops->bind(pos, cdev); if (ret) print_bind_err_msg(pos, cdev, ret); - continue; - } - - tzp = pos->tzp; - if (!tzp || !tzp->tbp) - continue; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(pos, cdev)) - continue; - tzp->tbp[i].cdev = cdev; - __bind(pos, tzp->tbp[i].trip_mask, cdev, - tzp->tbp[i].binding_limits, - tzp->tbp[i].weight); } } - - mutex_unlock(&thermal_list_lock); } /** @@ -933,17 +883,17 @@ __thermal_cooling_device_register(struct device_node *np, /* Add 'this' new cdev to the global cdev list */ mutex_lock(&thermal_list_lock); + list_add(&cdev->node, &thermal_cdev_list); - mutex_unlock(&thermal_list_lock); /* Update binding information for 'this' new cdev */ bind_cdev(cdev); - mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) if (atomic_cmpxchg(&pos->need_update, 1, 0)) thermal_zone_device_update(pos, THERMAL_EVENT_UNSPECIFIED); + mutex_unlock(&thermal_list_lock); return cdev; @@ -1138,16 +1088,6 @@ unlock_list: } EXPORT_SYMBOL_GPL(thermal_cooling_device_update); -static void __unbind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev) -{ - int i; - - for (i = 0; i < tz->num_trips; i++) - if (mask & (1 << i)) - thermal_zone_unbind_cooling_device(tz, i, cdev); -} - /** * thermal_cooling_device_unregister - removes a thermal cooling device * @cdev: the thermal cooling device to remove. @@ -1157,8 +1097,6 @@ static void __unbind(struct thermal_zone_device *tz, int mask, */ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) { - int i; - const struct thermal_zone_params *tzp; struct thermal_zone_device *tz; if (!cdev) @@ -1175,21 +1113,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) /* Unbind all thermal zones associated with 'this' cdev */ list_for_each_entry(tz, &thermal_tz_list, node) { - if (tz->ops->unbind) { + if (tz->ops->unbind) tz->ops->unbind(tz, cdev); - continue; - } - - if (!tz->tzp || !tz->tzp->tbp) - continue; - - tzp = tz->tzp; - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } } mutex_unlock(&thermal_list_lock); @@ -1200,41 +1125,20 @@ EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); static void bind_tz(struct thermal_zone_device *tz) { - int i, ret; + int ret; struct thermal_cooling_device *pos = NULL; - const struct thermal_zone_params *tzp = tz->tzp; - if (!tzp && !tz->ops->bind) + if (!tz->ops->bind) return; mutex_lock(&thermal_list_lock); - /* If there is ops->bind, try to use ops->bind */ - if (tz->ops->bind) { - list_for_each_entry(pos, &thermal_cdev_list, node) { - ret = tz->ops->bind(tz, pos); - if (ret) - print_bind_err_msg(tz, pos, ret); - } - goto exit; - } - - if (!tzp || !tzp->tbp) - goto exit; - list_for_each_entry(pos, &thermal_cdev_list, node) { - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(tz, pos)) - continue; - tzp->tbp[i].cdev = pos; - __bind(tz, tzp->tbp[i].trip_mask, pos, - tzp->tbp[i].binding_limits, - tzp->tbp[i].weight); - } + ret = tz->ops->bind(tz, pos); + if (ret) + print_bind_err_msg(tz, pos, ret); } -exit: + mutex_unlock(&thermal_list_lock); } @@ -1352,13 +1256,21 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t if (!tz) return ERR_PTR(-ENOMEM); + if (tzp) { + tz->tzp = kmemdup(tzp, sizeof(*tzp), GFP_KERNEL); + if (!tz->tzp) { + result = -ENOMEM; + goto free_tz; + } + } + INIT_LIST_HEAD(&tz->thermal_instances); ida_init(&tz->ida); mutex_init(&tz->lock); id = ida_alloc(&thermal_tz_ida, GFP_KERNEL); if (id < 0) { result = id; - goto free_tz; + goto free_tzp; } tz->id = id; @@ -1368,7 +1280,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ops->critical = thermal_zone_device_critical; tz->ops = ops; - tz->tzp = tzp; tz->device.class = thermal_class; tz->devdata = devdata; tz->trips = trips; @@ -1450,6 +1361,8 @@ release_device: tz = NULL; remove_id: ida_free(&thermal_tz_ida, id); +free_tzp: + kfree(tz->tzp); free_tz: kfree(tz); return ERR_PTR(result); @@ -1467,21 +1380,43 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, int n } EXPORT_SYMBOL_GPL(thermal_zone_device_register); +void *thermal_zone_device_priv(struct thermal_zone_device *tzd) +{ + return tzd->devdata; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_priv); + +const char *thermal_zone_device_type(struct thermal_zone_device *tzd) +{ + return tzd->type; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_type); + +int thermal_zone_device_id(struct thermal_zone_device *tzd) +{ + return tzd->id; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_id); + +struct device *thermal_zone_device(struct thermal_zone_device *tzd) +{ + return &tzd->device; +} +EXPORT_SYMBOL_GPL(thermal_zone_device); + /** * thermal_zone_device_unregister - removes the registered thermal zone device * @tz: the thermal zone device to remove */ void thermal_zone_device_unregister(struct thermal_zone_device *tz) { - int i, tz_id; - const struct thermal_zone_params *tzp; + int tz_id; struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; if (!tz) return; - tzp = tz->tzp; tz_id = tz->id; mutex_lock(&thermal_list_lock); @@ -1496,22 +1431,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) list_del(&tz->node); /* Unbind all cdevs associated with 'this' thermal zone */ - list_for_each_entry(cdev, &thermal_cdev_list, node) { - if (tz->ops->unbind) { + list_for_each_entry(cdev, &thermal_cdev_list, node) + if (tz->ops->unbind) tz->ops->unbind(tz, cdev); - continue; - } - - if (!tzp || !tzp->tbp) - break; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } - } mutex_unlock(&thermal_list_lock); @@ -1527,6 +1449,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) device_del(&tz->device); mutex_unlock(&tz->lock); + kfree(tz->tzp); + put_device(&tz->device); thermal_notify_tz_delete(tz_id); |