调试休眠遇到的案例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mike8825/article/details/81140159

1.无法休眠

    进入休眠后,如果系统不持有锁,将会写mem到/sys/power/state(可参考https://blog.csdn.net/mike8825/article/details/80420213),如果没走到这一步,即打印信息中没有suspend entry的打印,说明系统持由锁,这时可将锁打印出来。内核已经实现该接口,调用接口,可将下面的代码移植过去,就可找到具体的锁了。

#defined PM_PRINT_ENABLE
#ifdef PM_PRINT_ENABLE
static struct wake_lock messages_wakelock;
#endif
static int print_thread_interval = 30;
static int sprd_deep_print_thread(void *data)
{
	unsigned int cnt = 0;

	while (1) {
		wake_lock(&messages_wakelock);
		if (!pm_get_wakeup_count(&cnt, false)) {
			pr_info("PM: has wakeup events in progressing\n");
			pm_print_active_wakeup_sources();

		}
		msleep(100);
		wake_unlock(&messages_wakelock);
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(print_thread_interval * HZ);
	}

	return 0;
}

static void sprd_deep_debug_init(void)
{
#ifdef PM_PRINT_ENABLE
	struct task_struct *task;

	wake_lock_init(&messages_wakelock, WAKE_LOCK_SUSPEND,
		"pm_message_wakelock");
	task = kthread_create(sprd_deep_print_thread, NULL,
		"sprd_deep_print_thread");
	if (!task)
		pr_info("%s, Failed to create print thread", __func__);
	else
		wake_up_process(task);
#endif
}

drivers/base/power/wakeup.c 

void pm_print_active_wakeup_sources(void)
{
	struct wakeup_source *ws;
	int srcuidx, active = 0;
	struct wakeup_source *last_activity_ws = NULL;

	srcuidx = srcu_read_lock(&wakeup_srcu);
	list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
		if (ws->active) {
			pr_info("active wakeup source: %s\n", ws->name);
			active = 1;
		} else if (!active &&
			   (!last_activity_ws ||
			    ktime_to_ns(ws->last_time) >
			    ktime_to_ns(last_activity_ws->last_time))) {
			last_activity_ws = ws;
		}
	}

	if (!active && last_activity_ws)
		pr_info("last active wakeup source: %s\n",
			last_activity_ws->name);
	srcu_read_unlock(&wakeup_srcu, srcuidx);
}
EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);

休眠一段时间后,抓取内核信息,然后查找字符"active wakeup source"就可以知道谁持有锁了。

2.底电流大 

         1.摘芯片能降低底电流的,一般比较容易排查问题

          2.射频部分没有正确配置(开飞行模式底电流正常)

                   cat /sys/kernel/debug/rpm_state vmin的值为0,看内核信息也正常休眠了,原来刷机后,要接sim卡来激活, 这是平台的bug,可通过高通提供的补丁修复。

          3.功耗优化方法https://blog.csdn.net/mike8825/article/details/55823648

          4.遇到过一些使用中断方式的按键脚设置成输出会导致低电流大(展讯)

          5.高通的文档(kba-170221213554_4_高通通用功耗温升优化技术期刊.pdf)

          6.某些电源没有正确关闭(高通平台,通过ramdump抓取内存信息给高通分析,发现usb电源没有关闭)

                  (ramdump抓取方法https://blog.csdn.net/mike8825/article/details/79219913)

3.唤醒后硬件无法正常工作

1.记一次芯片休眠调试https://blog.csdn.net/mike8825/article/details/51763176

2.i2c死锁导致唤醒后,i2c无法正常工作(https://blog.csdn.net/mike8825/article/details/53454400

            3.打电话过程中,熄屏后过阵子喇叭没有声音,对方手机仍能听到声音,说明射频仍在工作。然来为了省电,打电话的过程中ap侧会休眠,休眠时PA的使能脚被设置成了高阻,导致PA不工作了。让PA的使能脚在休眠的时候上拉,就能保持高电平了。在正常的休眠中,PA的使能脚已经拉低,由于是弱上拉,不会导致芯片漏电,对休眠电流没影响。(展讯)

猜你喜欢

转载自blog.csdn.net/mike8825/article/details/81140159