thermal: core: Fix thermal zone suspend-resume synchronization
[platform/kernel/linux-rpi.git] / drivers / thermal / thermal_core.c
index 1494ffa..dee3022 100644 (file)
@@ -37,8 +37,6 @@ static LIST_HEAD(thermal_governor_list);
 static DEFINE_MUTEX(thermal_list_lock);
 static DEFINE_MUTEX(thermal_governor_lock);
 
-static atomic_t in_suspend;
-
 static struct thermal_governor *def_governor;
 
 /*
@@ -409,7 +407,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
 {
        int count;
 
-       if (atomic_read(&in_suspend))
+       if (tz->suspended)
                return;
 
        if (WARN_ONCE(!tz->ops->get_temp,
@@ -1532,17 +1530,35 @@ static int thermal_pm_notify(struct notifier_block *nb,
        case PM_HIBERNATION_PREPARE:
        case PM_RESTORE_PREPARE:
        case PM_SUSPEND_PREPARE:
-               atomic_set(&in_suspend, 1);
+               mutex_lock(&thermal_list_lock);
+
+               list_for_each_entry(tz, &thermal_tz_list, node) {
+                       mutex_lock(&tz->lock);
+
+                       tz->suspended = true;
+
+                       mutex_unlock(&tz->lock);
+               }
+
+               mutex_unlock(&thermal_list_lock);
                break;
        case PM_POST_HIBERNATION:
        case PM_POST_RESTORE:
        case PM_POST_SUSPEND:
-               atomic_set(&in_suspend, 0);
+               mutex_lock(&thermal_list_lock);
+
                list_for_each_entry(tz, &thermal_tz_list, node) {
+                       mutex_lock(&tz->lock);
+
+                       tz->suspended = false;
+
                        thermal_zone_device_init(tz);
-                       thermal_zone_device_update(tz,
-                                                  THERMAL_EVENT_UNSPECIFIED);
+                       __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+
+                       mutex_unlock(&tz->lock);
                }
+
+               mutex_unlock(&thermal_list_lock);
                break;
        default:
                break;