early_suspend / late_resume
20180822112943600.pngLCD显示屏是休眠了,触摸屏也休眠了,但是标准的Linux系统并没有进入休眠
Android在标准的Linux休眠与唤醒机制上又加了一层,就是early_suspend / late_resume
使用early_suspend()进行休眠的设备,它休眠的时刻早于其他设备,使用late_resume()唤醒的设备,它被唤醒的时刻要晚于其他设备。这对函数通常成对出现,当内核打开了CONFIG_EARLY_SUSPEND(Android默认打开)后,就可以使
用这组函数来代替驱动中标准的 suspend / resume接口。
wake_lock的用途只有一个,那就是防止系统进入休眠(这里的休眠,指的是标准的Linux的休眠,不包含使用early_suspend()进行休眠的设备,
使用early_suspend()的设备,在系统还有wake_lock锁的时候,也是要休眠的)
root@android:/ # ls /sys/power/
pm_async
state
wait_for_fb_sleep
wait_for_fb_wake
wake_lock
wake_unlock
wakeup_count
当state 的值变化时,内核会调用
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
request_suspend_state(state);//这里,进入了Android的休眠与唤醒的处理函数
if (!old_sleep && new_state != PM_SUSPEND_ON) {
state |= SUSPEND_REQUESTED;
queue_work(suspend_work_queue, &early_suspend_work);//在休眠的时候,去遍历执行early_suspend_work这个队列
} else if (old_sleep && new_state == PM_SUSPEND_ON) {
state &= ~SUSPEND_REQUESTED;
wake_lock(&main_wake_lock);
queue_work(suspend_work_queue, &late_resume_work);//在唤醒的时候,去遍历执行late_resume_work这个队列
}
int pm_suspend(suspend_state_t state)
{
if (state > PM_SUSPEND_ON && state < PM_SUSPEND_MAX)
return enter_state(state);//正如你所料,开始走Linux那套休眠的流程了
return -EINVAL;
}
驱动改动
比如在设备probe的时候做如下操作
struct early_suspend early_suspend;
early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; //等级,等级大小和suspend顺序一致,和resume顺序相反
early_suspend.suspend = xxx_early_suspend;//指定函数指针,需自己实现
early_suspend.resume = xxx_late_resume;
register_early_suspend(&early_suspend);//注册进核心,也就是加入刚才early_suspend_handlers那个链表
struct wake_lock chrg_lock;
wake_lock_init(&chrg_lock, WAKE_LOCK_SUSPEND, "xxx_wake_lock");//初始化类型为WAKE_LOCK_SUSPEND的wake_lock锁
#ifdef CONFIG_HAS_EARLYSUSPEND
static void xxx_early_suspend(struct early_suspend *h)
{
....
wake_lock(&chrg_lock);
....
}
static void xxx_late_resume(struct early_suspend *h)
{
.....
wake_unlock(&chrg_lock);
....
}
#endif
网友评论