summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorJonas Aaberg <jonas.aberg@stericsson.com>2011-11-22 10:13:10 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 10:59:28 +0200
commitff456e7674409437ef7e50699d6f23f35ed3791d (patch)
tree6785afa8c1941ccf59b6aad29f671f182342ad50 /kernel
parentb523e04f52b5f05631188b3a66352d246a7838b0 (diff)
power: suspend: Add make sure no race
If android via the wakelocks, hammers on suspend, there could be a race between the enable secondary cpus thread and the suspend call. Make suspend wait for any lingering enabling of secondary cpus. ST-Ericsson Linux next: - ST-Ericsson ID: 370799 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I1c346f9aed6afb76968a0e6058d534d8ebc158af Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/39194 Reviewed-by: QABUILD Reviewed-by: Bengt JONSSON <bengt.g.jonsson@stericsson.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/suspend.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 89ca6fa746b..e53c663a5e9 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -36,6 +36,10 @@ const char *const pm_states[PM_SUSPEND_MAX] = {
static const struct platform_suspend_ops *suspend_ops;
+static struct completion second_cpu_complete = {1,
+ __WAIT_QUEUE_HEAD_INITIALIZER((second_cpu_complete).wait)
+};
+
/**
* suspend_set_ops - Set the global suspend method table.
* @ops: Suspend operations to use.
@@ -262,6 +266,9 @@ static int plug_secondary_cpus(void *data)
suspend_test(TEST_DEVICES) ||
suspend_test(TEST_PLATFORM)))
enable_nonboot_cpus();
+
+ complete(&second_cpu_complete);
+
return 0;
}
@@ -284,6 +291,14 @@ static int enter_state(suspend_state_t state)
if (!mutex_trylock(&pm_mutex))
return -EBUSY;
+ /*
+ * Assure that previous started thread is completed before
+ * attempting to suspend again.
+ */
+ error = wait_for_completion_timeout(&second_cpu_complete,
+ msecs_to_jiffies(500));
+ WARN_ON(error == 0);
+
printk(KERN_INFO "PM: Syncing filesystems ... ");
sys_sync();
printk("done.\n");