summaryrefslogtreecommitdiff
authorQiufang Dai <qiufang.dai@amlogic.com>2019-09-26 14:06:15 (GMT)
committer zihuan.ling <zihuan.ling@amlogic.com>2019-10-15 07:04:16 (GMT)
commit380e19a9997e9f4136ff7ead777c3700e6ea7406 (patch)
tree46ff9588e78fef8907dae8a356509b10f901d5bc
parent909735d32baa6786266db683bf23377430d8c514 (diff)
downloadcommon-380e19a9997e9f4136ff7ead777c3700e6ea7406.zip
common-380e19a9997e9f4136ff7ead777c3700e6ea7406.tar.gz
common-380e19a9997e9f4136ff7ead777c3700e6ea7406.tar.bz2
suspend: fix freeze hangup which caused by insmod [1/1]
PD#TV-10472 Problem: When system on, enter freeze mode lead to flush deferd probe. Init.rc also run insmod in parallel, if insmod task atomic_inc(&probe_count), and this task is freezed, deadlock happends. Solution: Move flush deferd probe action before freeze task Verify: X32A0-T972 Change-Id: I8949db32aea14e2da37e77658a9c999af39e2c83 Signed-off-by: Qiufang Dai <qiufang.dai@amlogic.com>
Diffstat
-rw-r--r--drivers/base/power/main.c7
-rw-r--r--kernel/power/suspend.c23
2 files changed, 27 insertions, 3 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 7637314..c54fced 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -966,9 +966,10 @@ void dpm_complete(pm_message_t state)
}
list_splice(&list, &dpm_list);
mutex_unlock(&dpm_list_mtx);
-
+#ifndef CONFIG_AMLOGIC_MODIFY
/* Allow device probing and trigger re-probing of deferred devices */
device_unblock_probing();
+#endif
trace_suspend_resume(TPS("dpm_complete"), state.event, false);
}
@@ -1639,7 +1640,7 @@ int dpm_prepare(pm_message_t state)
trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
might_sleep();
-
+#ifndef CONFIG_AMLOGIC_MODIFY
/*
* Give a chance for the known devices to complete their probes, before
* disable probing of devices. This sync point is important at least
@@ -1653,7 +1654,7 @@ int dpm_prepare(pm_message_t state)
* instead. The normal behavior will be restored in dpm_complete().
*/
device_block_probing();
-
+#endif
mutex_lock(&dpm_list_mtx);
while (!list_empty(&dpm_list)) {
struct device *dev = to_device(dpm_list.next);
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 678e8fa..71050f5 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -33,6 +33,9 @@
#include <linux/wakeup_reason.h>
#include "power.h"
+#ifdef CONFIG_AMLOGIC_MODIFY
+#include "../../drivers/base/base.h"
+#endif
const char *pm_labels[] = { "mem", "standby", "freeze", NULL };
const char *pm_states[PM_SUSPEND_MAX];
@@ -289,6 +292,22 @@ static int suspend_prepare(suspend_state_t state)
goto Finish;
}
+#ifdef CONFIG_AMLOGIC_MODIFY
+ /*
+ * Give a chance for the known devices to complete their probes, before
+ * disable probing of devices. This sync point is important at least
+ * at boot time + hibernation restore.
+ */
+ wait_for_device_probe();
+ /*
+ * It is unsafe if probing of devices will happen during suspend or
+ * hibernation and system behavior will be unpredictable in this case.
+ * So, let's prohibit device's probing here and defer their probes
+ * instead. The normal behavior will be restored in dpm_complete().
+ */
+ device_block_probing();
+#endif
+
trace_suspend_resume(TPS("freeze_processes"), 0, true);
error = suspend_freeze_processes();
trace_suspend_resume(TPS("freeze_processes"), 0, false);
@@ -500,6 +519,10 @@ int suspend_devices_and_enter(suspend_state_t state)
static void suspend_finish(void)
{
suspend_thaw_processes();
+#ifdef CONFIG_AMLOGIC_MODIFY
+ /* Allow device probing and trigger re-probing of deferred devices */
+ device_unblock_probing();
+#endif
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
}