mirror of https://github.com/OpenIPC/firmware.git
115 lines
3.5 KiB
Diff
115 lines
3.5 KiB
Diff
diff -drupN a/kernel/power/suspend.c b/kernel/power/suspend.c
|
|
--- a/kernel/power/suspend.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/kernel/power/suspend.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -26,9 +26,11 @@
|
|
#include <linux/suspend.h>
|
|
#include <linux/syscore_ops.h>
|
|
#include <linux/ftrace.h>
|
|
+#include <linux/rtc.h>
|
|
#include <trace/events/power.h>
|
|
#include <linux/compiler.h>
|
|
#include <linux/moduleparam.h>
|
|
+#include <linux/wakeup_reason.h>
|
|
|
|
#include "power.h"
|
|
|
|
@@ -322,7 +324,8 @@ void __weak arch_suspend_enable_irqs(voi
|
|
*/
|
|
static int suspend_enter(suspend_state_t state, bool *wakeup)
|
|
{
|
|
- int error;
|
|
+ char suspend_abort[MAX_SUSPEND_ABORT_LEN];
|
|
+ int error, last_dev;
|
|
|
|
error = platform_suspend_prepare(state);
|
|
if (error)
|
|
@@ -330,7 +333,11 @@ static int suspend_enter(suspend_state_t
|
|
|
|
error = dpm_suspend_late(PMSG_SUSPEND);
|
|
if (error) {
|
|
+ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
|
|
+ last_dev %= REC_FAILED_NUM;
|
|
pr_err("PM: late suspend of devices failed\n");
|
|
+ log_suspend_abort_reason("%s device failed to power down",
|
|
+ suspend_stats.failed_devs[last_dev]);
|
|
goto Platform_finish;
|
|
}
|
|
error = platform_suspend_prepare_late(state);
|
|
@@ -339,7 +346,11 @@ static int suspend_enter(suspend_state_t
|
|
|
|
error = dpm_suspend_noirq(PMSG_SUSPEND);
|
|
if (error) {
|
|
+ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
|
|
+ last_dev %= REC_FAILED_NUM;
|
|
pr_err("PM: noirq suspend of devices failed\n");
|
|
+ log_suspend_abort_reason("noirq suspend of %s device failed",
|
|
+ suspend_stats.failed_devs[last_dev]);
|
|
goto Platform_early_resume;
|
|
}
|
|
error = platform_suspend_prepare_noirq(state);
|
|
@@ -363,8 +374,10 @@ static int suspend_enter(suspend_state_t
|
|
}
|
|
|
|
error = disable_nonboot_cpus();
|
|
- if (error || suspend_test(TEST_CPUS))
|
|
+ if (error || suspend_test(TEST_CPUS)) {
|
|
+ log_suspend_abort_reason("Disabling non-boot cpus failed");
|
|
goto Enable_cpus;
|
|
+ }
|
|
|
|
arch_suspend_disable_irqs();
|
|
BUG_ON(!irqs_disabled());
|
|
@@ -380,6 +393,9 @@ static int suspend_enter(suspend_state_t
|
|
state, false);
|
|
events_check_enabled = false;
|
|
} else if (*wakeup) {
|
|
+ pm_get_active_wakeup_sources(suspend_abort,
|
|
+ MAX_SUSPEND_ABORT_LEN);
|
|
+ log_suspend_abort_reason(suspend_abort);
|
|
error = -EBUSY;
|
|
}
|
|
syscore_resume();
|
|
@@ -427,6 +443,7 @@ int suspend_devices_and_enter(suspend_st
|
|
error = dpm_suspend_start(PMSG_SUSPEND);
|
|
if (error) {
|
|
pr_err("PM: 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");
|
|
goto Recover_platform;
|
|
}
|
|
suspend_test_finish("suspend devices");
|
|
@@ -527,6 +544,18 @@ static int enter_state(suspend_state_t s
|
|
return error;
|
|
}
|
|
|
|
+static void pm_suspend_marker(char *annotation)
|
|
+{
|
|
+ struct timespec ts;
|
|
+ struct rtc_time tm;
|
|
+
|
|
+ getnstimeofday(&ts);
|
|
+ rtc_time_to_tm(ts.tv_sec, &tm);
|
|
+ pr_info("PM: suspend %s %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n",
|
|
+ annotation, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
|
+ tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
|
|
+}
|
|
+
|
|
/**
|
|
* pm_suspend - Externally visible function for suspending the system.
|
|
* @state: System sleep state to enter.
|
|
@@ -541,6 +570,7 @@ int pm_suspend(suspend_state_t state)
|
|
if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX)
|
|
return -EINVAL;
|
|
|
|
+ pm_suspend_marker("entry");
|
|
error = enter_state(state);
|
|
if (error) {
|
|
suspend_stats.fail++;
|
|
@@ -548,6 +578,7 @@ int pm_suspend(suspend_state_t state)
|
|
} else {
|
|
suspend_stats.success++;
|
|
}
|
|
+ pm_suspend_marker("exit");
|
|
return error;
|
|
}
|
|
EXPORT_SYMBOL(pm_suspend);
|