From 3d8e3ad879441ae14c5957b933028daf39d252b0 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:02 +0100 Subject: thermal: add sanity check for the passive attribute Values below 1000 milli-celsius don't make sense and can cause the system to go into a thermal heart attack: the actual temperature will always be lower and thus the system will be throttled down to its lowest setting. An additional problem is that values below 1000 will show as 0 in /proc/acpi/thermal/TZx/trip_points:passive. cat passive 0 echo -n 90 >passive bash: echo: write error: Invalid argument echo -n 90000 >passive cat passive 90000 Signed-off-by: Frans Pop Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 6f8d8f97121..310e40ab00b 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -225,6 +225,12 @@ passive_store(struct device *dev, struct device_attribute *attr, if (!sscanf(buf, "%d\n", &state)) return -EINVAL; + /* sanity check: values below 1000 millicelcius don't make sense + * and can cause the system to go into a thermal heart attack + */ + if (state && state < 1000) + return -EINVAL; + if (state && !tz->forced_passive) { mutex_lock(&thermal_list_lock); list_for_each_entry(cdev, &thermal_cdev_list, node) { -- cgit v1.2.3 From e4143b0324a6a468cb00c4341cd20d60cc441252 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:03 +0100 Subject: thermal: Only set passive_delay for forced_passive cooling Setting polling_delay is useless as passive_delay has priority, so the value shown in proc isn't the actual polling delay. It also gives the impression to the user that he can change the polling interval through proc, while in fact he can't. Also, unset passive_delay when the forced passive trip point is unbound to allow polling to be disabled. Signed-off-by: Frans Pop Acked-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 310e40ab00b..663c2fdba77 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -241,6 +241,8 @@ passive_store(struct device *dev, struct device_attribute *attr, cdev); } mutex_unlock(&thermal_list_lock); + if (!tz->passive_delay) + tz->passive_delay = 1000; } else if (!state && tz->forced_passive) { mutex_lock(&thermal_list_lock); list_for_each_entry(cdev, &thermal_cdev_list, node) { @@ -251,17 +253,12 @@ passive_store(struct device *dev, struct device_attribute *attr, cdev); } mutex_unlock(&thermal_list_lock); + tz->passive_delay = 0; } tz->tc1 = 1; tz->tc2 = 1; - if (!tz->passive_delay) - tz->passive_delay = 1000; - - if (!tz->polling_delay) - tz->polling_delay = 10000; - tz->forced_passive = state; thermal_zone_device_update(tz); -- cgit v1.2.3 From 3767cb54ac718eb049d2a29f7a575ab923550ba5 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:04 +0100 Subject: thermal: disable polling if passive_delay and polling_delay are both unset Otherwise polling will continue for the thermal zone even when it is no longer needed, for example because forced passive cooling was disabled. Signed-off-by: Frans Pop Acked-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 663c2fdba77..3bc72ea57e0 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -1019,6 +1019,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) thermal_zone_device_set_polling(tz, tz->passive_delay); else if (tz->polling_delay) thermal_zone_device_set_polling(tz, tz->polling_delay); + else + thermal_zone_device_set_polling(tz, 0); mutex_unlock(&tz->lock); } EXPORT_SYMBOL(thermal_zone_device_update); -- cgit v1.2.3 From edb949185210365f107ddc5efa60df105d25e1d7 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 15 Dec 2009 22:46:50 +0100 Subject: thermal: Fix test of unsigned in thermal_cooling_device_cur_state_store() state is unsigned long so the test did not work. Signed-off-by: Roel Kluin Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 6f8d8f97121..800e0c56cc8 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -374,7 +374,7 @@ thermal_cooling_device_cur_state_store(struct device *dev, if (!sscanf(buf, "%ld\n", &state)) return -EINVAL; - if (state < 0) + if ((long)state < 0) return -EINVAL; result = cdev->ops->set_cur_state(cdev, state); -- cgit v1.2.3