summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/thermal/thermal_core.c88
1 files changed, 46 insertions, 42 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 03f5ac996a7a..f54c2d2544a4 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1684,6 +1684,48 @@ static void thermal_zone_device_resume(struct work_struct *work)
mutex_unlock(&tz->lock);
}
+static void thermal_zone_pm_prepare(struct thermal_zone_device *tz)
+{
+ mutex_lock(&tz->lock);
+
+ if (tz->resuming) {
+ /*
+ * thermal_zone_device_resume() queued up for this zone has not
+ * acquired the lock yet, so release it to let the function run
+ * and wait util it has done the work.
+ */
+ mutex_unlock(&tz->lock);
+
+ wait_for_completion(&tz->resume);
+
+ mutex_lock(&tz->lock);
+ }
+
+ tz->suspended = true;
+
+ mutex_unlock(&tz->lock);
+}
+
+static void thermal_zone_pm_complete(struct thermal_zone_device *tz)
+{
+ mutex_lock(&tz->lock);
+
+ cancel_delayed_work(&tz->poll_queue);
+
+ reinit_completion(&tz->resume);
+ tz->resuming = true;
+
+ /*
+ * Replace the work function with the resume one, which will restore the
+ * original work function and schedule the polling work if needed.
+ */
+ INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_resume);
+ /* Queue up the work without a delay. */
+ mod_delayed_work(system_freezable_power_efficient_wq, &tz->poll_queue, 0);
+
+ mutex_unlock(&tz->lock);
+}
+
static int thermal_pm_notify(struct notifier_block *nb,
unsigned long mode, void *_unused)
{
@@ -1695,27 +1737,8 @@ static int thermal_pm_notify(struct notifier_block *nb,
case PM_SUSPEND_PREPARE:
mutex_lock(&thermal_list_lock);
- list_for_each_entry(tz, &thermal_tz_list, node) {
- mutex_lock(&tz->lock);
-
- if (tz->resuming) {
- /*
- * thermal_zone_device_resume() queued up for
- * this zone has not acquired the lock yet, so
- * release it to let the function run and wait
- * util it has done the work.
- */
- mutex_unlock(&tz->lock);
-
- wait_for_completion(&tz->resume);
-
- mutex_lock(&tz->lock);
- }
-
- tz->suspended = true;
-
- mutex_unlock(&tz->lock);
- }
+ list_for_each_entry(tz, &thermal_tz_list, node)
+ thermal_zone_pm_prepare(tz);
mutex_unlock(&thermal_list_lock);
break;
@@ -1724,27 +1747,8 @@ static int thermal_pm_notify(struct notifier_block *nb,
case PM_POST_SUSPEND:
mutex_lock(&thermal_list_lock);
- list_for_each_entry(tz, &thermal_tz_list, node) {
- mutex_lock(&tz->lock);
-
- cancel_delayed_work(&tz->poll_queue);
-
- reinit_completion(&tz->resume);
- tz->resuming = true;
-
- /*
- * Replace the work function with the resume one, which
- * will restore the original work function and schedule
- * the polling work if needed.
- */
- INIT_DELAYED_WORK(&tz->poll_queue,
- thermal_zone_device_resume);
- /* Queue up the work without a delay. */
- mod_delayed_work(system_freezable_power_efficient_wq,
- &tz->poll_queue, 0);
-
- mutex_unlock(&tz->lock);
- }
+ list_for_each_entry(tz, &thermal_tz_list, node)
+ thermal_zone_pm_complete(tz);
mutex_unlock(&thermal_list_lock);
break;