author | Qiufang 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) |
commit | 380e19a9997e9f4136ff7ead777c3700e6ea7406 (patch) | |
tree | 46ff9588e78fef8907dae8a356509b10f901d5bc | |
parent | 909735d32baa6786266db683bf23377430d8c514 (diff) | |
download | common-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>
-rw-r--r-- | drivers/base/power/main.c | 7 | ||||
-rw-r--r-- | kernel/power/suspend.c | 23 |
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(); } |