1、debug开关
默认情况,有些休眠过程的log会在唤醒的时候打印出来,配置以下参数休眠时即可打印,可以及时看到信息
echo N > /sys/module/printk/parameters/console_suspend; (默认console suspend 会导致部分休眠的log被缓存,唤醒的时候才输出)
echo 1 > sys/module/kernel/parameters/initcall_debug; (打印休眠devices name)bootargs = "earlycon=uart8250,mmio32,0xff550000 conso le=ttyFIQ0 init=/init swiotlb=1 kpti=0 no_console_suspend initcall_debug=1";
echo 1 > sys/power/pm_print_times (打印各设备休眠唤醒执行的时间,做休眠唤醒速度优化使用)
2、deepsleep 等级
KKKKD7200:/ # cat sys/power/pm_test
[none] core processors platform devices freezer (正常休眠顺序是从freezer -》devices -》...->none)
通过节点配置,深度休眠的等级。
echo core > sys/power/pm_test (表示linux 休眠完成,不进入trust 休眠)
可以用在一些休眠死机的情况下, 确认在哪个部分代码死机。
比如是platform 部分休眠死机,还是在devices 部分休眠死机的。
3、查看休眠次数
KKKKD7200:/ # cat sys/kernel/debug/suspend_stats
success: 170
fail: 155
failed_freeze: 121
failed_prepare: 0
failed_suspend: 33
failed_suspend_late: 0
failed_suspend_noirq: 0
failed_resume: 0
failed_resume_early: 0
failed_resume_noirq: 0
failures:
last_failed_dev: alarmtimer
alarmtimer
last_failed_errno: -16
-16
last_failed_step: suspend
freeze
KKKKD7200:/ #
4、查看休眠失败原因
原因1: 有模块suspend 返回错误
原因2: 有事件中断,以下以触摸中断为例
KKKKD7200:/ # cat /sys/power/suspend_stats/last_failed_dev
KKKKD7200:/ # cat sys/kernel/wakeup_reasons/*
Abort: Pending Wakeup Sources: event1 4.605694586 18446744073709551615.999999416
KKKKD7200:/ # getevent
add device 1: /dev/input/event1
name: "gslX680-pad"
130|KKKKD7200:/ # cat proc/interrupts |grep gsl
56: 671520 0 0 0 gpio0 11 Level gslX680-pad
这个错误就是gslx680 一直触发中断导致无法正常休眠。
5、查看唤醒源(休眠的时候会被清除,所以如果唤醒之后再次进入休眠并且休眠失败就无法获取到)
KKKKD7200:/ # num=cat sys/power/pm_wakeup_irq
&&cat proc/interrupts |grep $num
116: 184 0 0 0 0 0 gpio1 18 Level rk817
6、查看休眠锁
以下就是阻止休眠的lock
KKKKD7200:/ # cat ./sys/kernel/debug/wakeup_sources | busybox awk '{if (6)print1"\t"$6}'
name active_since
PowerManagerService.WakeLocks 54292
rockchip_otg 472523
或者:
1|console:/ # echo 1 > sys/power/wakeup_count
[ 168.510728] active wakeup source: rockchip_otg
手动释放lock
KKKKD7200:/ # echo PowerManagerService.WakeLocks> sys/power/wake_unlock
可以自行添加lock,禁止系统进深度休眠
KKKKD7200:/ # echo test_lock > sys/power/wake_lock
unlock:
KKKKD7200:/ # echo test_lock > sys/power/wake_unlock
7、强制进入休眠
KKKKD7200:/ # echo mem > sys/power/state
8、gpio无法唤醒问题
a、cpu gpio 电源域和clk是否有关闭
b、初始化需要定义 device_init_wakeup(dev, true); enable_irq_wake(motg->irq);
9、查看唤醒源
cat sys/power/pm_wakeup_irq
+++ b/drivers/base/platform.c
@@ -1030,8 +1030,10 @@ static int platform_legacy_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- if (dev->driver && pdrv->resume)
+ if (dev->driver && pdrv->resume) {
ret = pdrv->resume(pdev);
+ pr_err ("===%pF===", pdrv->resume);
+ }
return ret;
}
@@ -1067,10 +1069,13 @@ int platform_pm_resume(struct device *dev)
return 0;
if (drv->pm) {
- if (drv->pm->resume)
+ if (drv->pm->resume) {
ret = drv->pm->resume(dev);
+ pr_err ("===%pF===", drv->pm->resume);
+ }
} else {
ret = platform_legacy_resume(dev);
+ pr_err ("===%pF===", platform_legacy_resume);
}
10、/sys/power/state 代码位置kernel/power/main.c state_store
11、休眠时间统计
console:/ # cat d/sleep_time
time (secs) count
------------------------------
4 - 8 3
8 - 16 1
16 - 32 2
32 - 64 2
64 - 128 8
128 - 256 16
256 - 512 24
512 - 1024 13
12、唤醒更新系统时间:
休眠时间统计有两种方式,
1、rtc 是通用的
2、clock source 32k计算
流程:
1、timekeeping_resume (kernel/time/timekeeping.c) 判断clock source是否支持
2、如果平台不支持,suspend_timing_needed=true, rtc_resume会根据休眠前后的时间差,更新到系统时间
drivers/rtc/class.c rtc_resume
13. 快速休眠测试:
while
do
echo +10 > /sys/class/rtc/rtc0/wakealarm
echo mem > sys/power/state
done &