blob: d7ab37a040a81db0c0d7f1b4dcaa9e44c1ed5e16 [file] [log] [blame]
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");