| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: zhuguangqing <zhuguangqing@xiaomi.com> |
| Date: Fri, 23 Aug 2019 09:04:06 +0800 |
| Subject: 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 <zhuguangqing@xiaomi.com> |
| --- |
| 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 |
| --- a/drivers/base/power/main.c |
| +++ b/drivers/base/power/main.c |
| @@ -1901,6 +1901,7 @@ int dpm_prepare(pm_message_t state) |
| } |
| pr_info("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 |
| --- a/kernel/power/suspend.c |
| +++ b/kernel/power/suspend.c |
| @@ -490,7 +490,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)) |
| @@ -509,8 +509,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"); |