From 81daa79b753d985922ae57a00b16addcc75f70b2 Mon Sep 17 00:00:00 2001 From: zhuguangqing Date: Fri, 23 Aug 2019 09:04:06 +0800 Subject: [PATCH] ANDROID: Log which device failed to suspend in dpm_suspend_start() Problem background: In the process of suspend, maybe some device suspend callback failed in dpm_suspend_start()/dpm_prepare()/dpm_suspend(). Because it's after suspend_console(), so printf() is disabled now. Currently we can see "Some devices failed to suspend, or early wake event detected" by log_suspend_abort_reason() in bugreport. There are many devices but we don't know which exactly device failed. So we want to do a little change to record which device failed. Note: I checked upstream LTS kernel, then I found the patch can not be sent upstream, because it uses function log_suspend_abort_reason() in wakeup_reason.c, the initial patch(https://patchwork.kernel.org/patch/3827331/) for adding /kernel/power/wakeup_reason.c is not accepted by upstream which was merged in AOSP common kernels. So maybe the patch could only be sent to AOSP common kernels. Test: manual - Use modified version for daily use two days, from bugreport we can see which device failed. Bug: 120445600 Change-Id: I326c87ca1263496db79d08ec615f12fc22452d7a Signed-off-by: zhuguangqing --- drivers/base/power/main.c | 1 + kernel/power/suspend.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 554479233360..5cf624a5b2bb 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -2022,6 +2022,7 @@ int dpm_prepare(pm_message_t state) printk(KERN_INFO "PM: Device %s not prepared " "for power transition: code %d\n", dev_name(dev), error); + dpm_save_failed_dev(dev_name(dev)); put_device(dev); break; } diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 36cb7edb9126..3ef2c536652d 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -496,7 +496,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) */ int suspend_devices_and_enter(suspend_state_t state) { - int error; + int error, last_dev; bool wakeup = false; if (!sleep_state_supported(state)) @@ -512,8 +512,11 @@ int suspend_devices_and_enter(suspend_state_t state) suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); if (error) { + last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; + last_dev %= REC_FAILED_NUM; pr_err("Some devices failed to suspend, or early wake event detected\n"); - log_suspend_abort_reason("Some devices failed to suspend, or early wake event detected"); + log_suspend_abort_reason("%s device failed to suspend, or early wake event detected", + suspend_stats.failed_devs[last_dev]); goto Recover_platform; } suspend_test_finish("suspend devices");