aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Yu <yu.c.chen@intel.com>2015-10-30 04:32:10 -0400
committerZhang Rui <rui.zhang@intel.com>2015-12-29 03:00:00 -0500
commit4511f7166a2deb5f7a578cf87fd2fe1ae83527e3 (patch)
tree27511588f566ac27bbc92ce8bb4b676cbcf7d4a5
parentff140fea847e1c2002a220571ab106c2456ed252 (diff)
Thermal: do thermal zone update after a cooling device registered
When a new cooling device is registered, we need to update the thermal zone to set the new registered cooling device to a proper state. This fixes a problem that the system is cool, while the fan devices are left running on full speed after boot, if fan device is registered after thermal zone device. Here is the history of why current patch looks like this: https://patchwork.kernel.org/patch/7273041/ CC: <stable@vger.kernel.org> #3.18+ Reference:https://bugzilla.kernel.org/show_bug.cgi?id=92431 Tested-by: Manuel Krause <manuelkrause@netscape.net> Tested-by: szegad <szegadlo@poczta.onet.pl> Tested-by: prash <prash.n.rao@gmail.com> Tested-by: amish <ammdispose-arch@yahoo.com> Reviewed-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Chen Yu <yu.c.chen@intel.com>
-rw-r--r--drivers/thermal/thermal_core.c14
-rw-r--r--include/linux/thermal.h2
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 9aae767bf39b..ba08b5521382 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1341,6 +1341,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
1341 if (!result) { 1341 if (!result) {
1342 list_add_tail(&dev->tz_node, &tz->thermal_instances); 1342 list_add_tail(&dev->tz_node, &tz->thermal_instances);
1343 list_add_tail(&dev->cdev_node, &cdev->thermal_instances); 1343 list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
1344 atomic_set(&tz->need_update, 1);
1344 } 1345 }
1345 mutex_unlock(&cdev->lock); 1346 mutex_unlock(&cdev->lock);
1346 mutex_unlock(&tz->lock); 1347 mutex_unlock(&tz->lock);
@@ -1450,6 +1451,7 @@ __thermal_cooling_device_register(struct device_node *np,
1450 const struct thermal_cooling_device_ops *ops) 1451 const struct thermal_cooling_device_ops *ops)
1451{ 1452{
1452 struct thermal_cooling_device *cdev; 1453 struct thermal_cooling_device *cdev;
1454 struct thermal_zone_device *pos = NULL;
1453 int result; 1455 int result;
1454 1456
1455 if (type && strlen(type) >= THERMAL_NAME_LENGTH) 1457 if (type && strlen(type) >= THERMAL_NAME_LENGTH)
@@ -1494,6 +1496,12 @@ __thermal_cooling_device_register(struct device_node *np,
1494 /* Update binding information for 'this' new cdev */ 1496 /* Update binding information for 'this' new cdev */
1495 bind_cdev(cdev); 1497 bind_cdev(cdev);
1496 1498
1499 mutex_lock(&thermal_list_lock);
1500 list_for_each_entry(pos, &thermal_tz_list, node)
1501 if (atomic_cmpxchg(&pos->need_update, 1, 0))
1502 thermal_zone_device_update(pos);
1503 mutex_unlock(&thermal_list_lock);
1504
1497 return cdev; 1505 return cdev;
1498} 1506}
1499 1507
@@ -1826,6 +1834,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
1826 tz->trips = trips; 1834 tz->trips = trips;
1827 tz->passive_delay = passive_delay; 1835 tz->passive_delay = passive_delay;
1828 tz->polling_delay = polling_delay; 1836 tz->polling_delay = polling_delay;
1837 /* A new thermal zone needs to be updated anyway. */
1838 atomic_set(&tz->need_update, 1);
1829 1839
1830 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1840 dev_set_name(&tz->device, "thermal_zone%d", tz->id);
1831 result = device_register(&tz->device); 1841 result = device_register(&tz->device);
@@ -1921,7 +1931,9 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
1921 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); 1931 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1922 1932
1923 thermal_zone_device_reset(tz); 1933 thermal_zone_device_reset(tz);
1924 thermal_zone_device_update(tz); 1934 /* Update the new thermal zone and mark it as already updated. */
1935 if (atomic_cmpxchg(&tz->need_update, 1, 0))
1936 thermal_zone_device_update(tz);
1925 1937
1926 return tz; 1938 return tz;
1927 1939
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 103fcbe6bdaf..e13a1ace50e9 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -170,6 +170,7 @@ struct thermal_attr {
170 * @forced_passive: If > 0, temperature at which to switch on all ACPI 170 * @forced_passive: If > 0, temperature at which to switch on all ACPI
171 * processor cooling devices. Currently only used by the 171 * processor cooling devices. Currently only used by the
172 * step-wise governor. 172 * step-wise governor.
173 * @need_update: if equals 1, thermal_zone_device_update needs to be invoked.
173 * @ops: operations this &thermal_zone_device supports 174 * @ops: operations this &thermal_zone_device supports
174 * @tzp: thermal zone parameters 175 * @tzp: thermal zone parameters
175 * @governor: pointer to the governor for this thermal zone 176 * @governor: pointer to the governor for this thermal zone
@@ -197,6 +198,7 @@ struct thermal_zone_device {
197 int emul_temperature; 198 int emul_temperature;
198 int passive; 199 int passive;
199 unsigned int forced_passive; 200 unsigned int forced_passive;
201 atomic_t need_update;
200 struct thermal_zone_device_ops *ops; 202 struct thermal_zone_device_ops *ops;
201 struct thermal_zone_params *tzp; 203 struct thermal_zone_params *tzp;
202 struct thermal_governor *governor; 204 struct thermal_governor *governor;