diff options
Diffstat (limited to 'drivers/thermal/thermal_core.c')
-rw-r--r-- | drivers/thermal/thermal_core.c | 83 |
1 files changed, 34 insertions, 49 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 6a5d0ae5d7a4..117eeaf7dd24 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -295,27 +295,14 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, cancel_delayed_work(&tz->poll_queue); } -static inline bool should_stop_polling(struct thermal_zone_device *tz) -{ - return !thermal_zone_device_is_enabled(tz); -} - static void monitor_thermal_zone(struct thermal_zone_device *tz) { - bool stop; - - stop = should_stop_polling(tz); - - mutex_lock(&tz->lock); - - if (!stop && tz->passive) + if (tz->mode != THERMAL_DEVICE_ENABLED) + thermal_zone_device_set_polling(tz, 0); + else if (tz->passive) thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies); - else if (!stop && tz->polling_delay_jiffies) + else if (tz->polling_delay_jiffies) thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); - 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) @@ -383,18 +370,13 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) handle_critical_trips(tz, trip, trip_temp, type); else handle_non_critical_trips(tz, trip); - /* - * Alright, we handled this trip successfully. - * So, start monitoring again. - */ - monitor_thermal_zone(tz); } static void update_temperature(struct thermal_zone_device *tz) { int temp, ret; - ret = thermal_zone_get_temp(tz, &temp); + ret = __thermal_zone_get_temp(tz, &temp); if (ret) { if (ret != -EAGAIN) dev_warn(&tz->device, @@ -403,10 +385,8 @@ static void update_temperature(struct thermal_zone_device *tz) return; } - mutex_lock(&tz->lock); tz->last_temperature = tz->temperature; tz->temperature = temp; - mutex_unlock(&tz->lock); trace_thermal_temperature(tz); @@ -469,15 +449,9 @@ EXPORT_SYMBOL_GPL(thermal_zone_device_disable); int thermal_zone_device_is_enabled(struct thermal_zone_device *tz) { - enum thermal_device_mode mode; - - mutex_lock(&tz->lock); - - mode = tz->mode; + lockdep_assert_held(&tz->lock); - mutex_unlock(&tz->lock); - - return mode == THERMAL_DEVICE_ENABLED; + return tz->mode == THERMAL_DEVICE_ENABLED; } void thermal_zone_device_update(struct thermal_zone_device *tz, @@ -485,9 +459,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, { int count; - if (should_stop_polling(tz)) - return; - if (atomic_read(&in_suspend)) return; @@ -495,14 +466,23 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, "'get_temp' ops set\n", __func__)) return; + mutex_lock(&tz->lock); + + if (!thermal_zone_device_is_enabled(tz)) + goto out; + update_temperature(tz); - thermal_zone_set_trips(tz); + __thermal_zone_set_trips(tz); tz->notify_event = event; for (count = 0; count < tz->num_trips; count++) handle_thermal_trip(tz, count); + + monitor_thermal_zone(tz); +out: + mutex_unlock(&tz->lock); } EXPORT_SYMBOL_GPL(thermal_zone_device_update); @@ -1206,13 +1186,26 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t return ERR_PTR(-EINVAL); } - if (type && strlen(type) >= THERMAL_NAME_LENGTH) { + if (strlen(type) >= THERMAL_NAME_LENGTH) { pr_err("Thermal zone name (%s) too long, should be under %d chars\n", type, THERMAL_NAME_LENGTH); return ERR_PTR(-EINVAL); } - if (num_trips > THERMAL_MAX_TRIPS || num_trips < 0 || mask >> num_trips) { + /* + * Max trip count can't exceed 31 as the "mask >> num_trips" condition. + * For example, shifting by 32 will result in compiler warning: + * warning: right shift count >= width of type [-Wshift-count- overflow] + * + * Also "mask >> num_trips" will always be true with 32 bit shift. + * E.g. mask = 0x80000000 for trip id 31 to be RW. Then + * mask >> 32 = 0x80000000 + * This will result in failure for the below condition. + * + * Check will be true when the bit 31 of the mask is set. + * 32 bit shift will cause overflow of 4 byte integer. + */ + if (num_trips > (BITS_PER_TYPE(int) - 1) || num_trips < 0 || mask >> num_trips) { pr_err("Incorrect number of thermal trips\n"); return ERR_PTR(-EINVAL); } @@ -1239,7 +1232,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t } tz->id = id; - strlcpy(tz->type, type, sizeof(tz->type)); + strscpy(tz->type, type, sizeof(tz->type)); result = dev_set_name(&tz->device, "thermal_zone%d", tz->id); if (result) @@ -1329,6 +1322,7 @@ free_tz: kfree(tz); return ERR_PTR(result); } +EXPORT_SYMBOL_GPL(thermal_zone_device_register_with_trips); struct thermal_zone_device *thermal_zone_device_register(const char *type, int ntrips, int mask, void *devdata, struct thermal_zone_device_ops *ops, @@ -1457,9 +1451,6 @@ static int thermal_pm_notify(struct notifier_block *nb, case PM_POST_SUSPEND: atomic_set(&in_suspend, 0); list_for_each_entry(tz, &thermal_tz_list, node) { - if (!thermal_zone_device_is_enabled(tz)) - continue; - thermal_zone_device_init(tz); thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); @@ -1491,10 +1482,6 @@ static int __init thermal_init(void) if (result) goto unregister_governors; - result = of_parse_thermal_zones(); - if (result) - goto unregister_class; - result = register_pm_notifier(&thermal_pm_nb); if (result) pr_warn("Thermal: Can not register suspend notifier, return %d\n", @@ -1502,8 +1489,6 @@ static int __init thermal_init(void) return 0; -unregister_class: - class_unregister(&thermal_class); unregister_governors: thermal_unregister_governors(); error: |