Skip to content

Commit ab48276

Browse files
zhang-ruisashalevin
authored andcommitted
Thermal: handle thermal zone device properly during system sleep
[ Upstream commit ff140fe ] Current thermal code does not handle system sleep well because 1. the cooling device cooling state may be changed during suspend 2. the previous temperature reading becomes invalid after resumed because it is got before system sleep 3. updating thermal zone device during suspending/resuming is wrong because some devices may have already been suspended or may have not been resumed. Thus, the proper way to do this is to cancel all thermal zone device update requirements during suspend/resume, and after all the devices have been resumed, reset and update every registered thermal zone devices. This also fixes a regression introduced by: Commit 19593a1 ("ACPI / fan: convert to platform driver") Because, with above commit applied, all the fan devices are attached to the acpi_general_pm_domain, and they are turned on by the pm_domain automatically after resume, without the awareness of thermal core. CC: <[email protected]> #3.18+ Reference: https://bugzilla.kernel.org/show_bug.cgi?id=78201 Reference: https://bugzilla.kernel.org/show_bug.cgi?id=91411 Tested-by: Manuel Krause <[email protected]> Tested-by: szegad <[email protected]> Tested-by: prash <[email protected]> Tested-by: amish <[email protected]> Tested-by: Matthias <[email protected]> Reviewed-by: Javi Merino <[email protected]> Signed-off-by: Zhang Rui <[email protected]> Signed-off-by: Chen Yu <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 247d403 commit ab48276

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

drivers/thermal/thermal_core.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/of.h>
3838
#include <net/netlink.h>
3939
#include <net/genetlink.h>
40+
#include <linux/suspend.h>
4041

4142
#define CREATE_TRACE_POINTS
4243
#include <trace/events/thermal.h>
@@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list);
5960
static DEFINE_MUTEX(thermal_list_lock);
6061
static DEFINE_MUTEX(thermal_governor_lock);
6162

63+
static atomic_t in_suspend;
64+
6265
static struct thermal_governor *def_governor;
6366

6467
static struct thermal_governor *__find_governor(const char *name)
@@ -493,6 +496,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
493496
{
494497
int count;
495498

499+
if (atomic_read(&in_suspend))
500+
return;
501+
496502
if (!tz->ops->get_temp)
497503
return;
498504

@@ -1825,6 +1831,36 @@ static void thermal_unregister_governors(void)
18251831
thermal_gov_user_space_unregister();
18261832
}
18271833

1834+
static int thermal_pm_notify(struct notifier_block *nb,
1835+
unsigned long mode, void *_unused)
1836+
{
1837+
struct thermal_zone_device *tz;
1838+
1839+
switch (mode) {
1840+
case PM_HIBERNATION_PREPARE:
1841+
case PM_RESTORE_PREPARE:
1842+
case PM_SUSPEND_PREPARE:
1843+
atomic_set(&in_suspend, 1);
1844+
break;
1845+
case PM_POST_HIBERNATION:
1846+
case PM_POST_RESTORE:
1847+
case PM_POST_SUSPEND:
1848+
atomic_set(&in_suspend, 0);
1849+
list_for_each_entry(tz, &thermal_tz_list, node) {
1850+
thermal_zone_device_reset(tz);
1851+
thermal_zone_device_update(tz);
1852+
}
1853+
break;
1854+
default:
1855+
break;
1856+
}
1857+
return 0;
1858+
}
1859+
1860+
static struct notifier_block thermal_pm_nb = {
1861+
.notifier_call = thermal_pm_notify,
1862+
};
1863+
18281864
static int __init thermal_init(void)
18291865
{
18301866
int result;
@@ -1845,6 +1881,11 @@ static int __init thermal_init(void)
18451881
if (result)
18461882
goto exit_netlink;
18471883

1884+
result = register_pm_notifier(&thermal_pm_nb);
1885+
if (result)
1886+
pr_warn("Thermal: Can not register suspend notifier, return %d\n",
1887+
result);
1888+
18481889
return 0;
18491890

18501891
exit_netlink:
@@ -1864,6 +1905,7 @@ static int __init thermal_init(void)
18641905

18651906
static void __exit thermal_exit(void)
18661907
{
1908+
unregister_pm_notifier(&thermal_pm_nb);
18671909
of_thermal_destroy_zones();
18681910
genetlink_exit();
18691911
class_unregister(&thermal_class);

0 commit comments

Comments
 (0)