early suspend

晒晒 early suspend 的源代码~
我对PM这块不太懂,不知道early suspend 干啥的,具体怎么干的。就知道应该是PM相关的,进入和退出休眠状态需要的代码,即suspend和resume。

1. early_suspend 数据结构:

struct early_suspend {
    #ifdef CONFIG_HAS_EARLYSUSPEND                //判断是否配置了 CONFIG_EARLY_SUSPEND 选项。
        struct list_head link;                    //suspend_work_queue链表
        int level;                                //suspend等级
        void (*suspend)(struct early_suspend *h);  //进入休眠
        void (*resume)(struct early_suspend *h);   //退出休眠
    #endif
    };
2. level,suspend分为3个等级

/* The early_suspend structure defines suspend and resume hooks to be called
     * when the user visible sleep state of the system changes, and a level to
     * control the order. They can be used to turn off the screen and input
     * devices that are not used for wakeup.
     * Suspend handlers are called in low to high level order, resume handlers are
     * called in the opposite order. If, when calling register_early_suspend,
     * the suspend handlers have already been called without a matching call to the
     * resume handlers, the suspend handler will be called directly from
     * register_early_suspend. This direct call can violate the normal level order.
     */
    enum {
        EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,   //level数值越小,suspend调用的越早。resume相反。
        EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100,
        EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,
    };
3. 注册和注销 early_suspend 工作
void register_early_suspend(struct early_suspend *handler)
    {
        struct list_head *pos;                          //链表头
        mutex_lock(&early_suspend_lock);                 //互斥锁 early_suspend_lock
        list_for_each(pos, &early_suspend_handlers) {      //iterate over a list
            struct early_suspend *e;
            e = list_entry(pos, struct early_suspend, link);   //get the struct for this entry。
            if (e->level > handler->level)                 //判断优先级
                break;
        }
        list_add_tail(&handler->link, pos);       //把early_suspend 加到list尾部。
        if ((state & SUSPENDED) && handler->suspend)
            handler->suspend(handler);
        mutex_unlock(&early_suspend_lock);
    }
    EXPORT_SYMBOL(register_early_suspend);

    void unregister_early_suspend(struct early_suspend *handler)
    {
        mutex_lock(&early_suspend_lock);
        list_del(&handler->link);
        mutex_unlock(&early_suspend_lock);
    }
    EXPORT_SYMBOL(unregister_early_suspend);
4. early_suspend 和 late_resume 具体实现:
static void early_suspend(struct work_struct *work)
    {
        struct early_suspend *pos;
        unsigned long irqflags;
        int abort = 0;
        mutex_lock(&early_suspend_lock);
        spin_lock_irqsave(&state_lock, irqflags);     //自旋锁 state_lock
        if (state == SUSPEND_REQUESTED)
            state |= SUSPENDED;
        else
            abort = 1;
        spin_unlock_irqrestore(&state_lock, irqflags);
        if (abort) {
            if (debug_mask & DEBUG_SUSPEND)
                pr_info("early_suspend: abort, state %d\n", state);
            mutex_unlock(&early_suspend_lock);
            goto abort;
        }
        if (debug_mask & DEBUG_SUSPEND)
            pr_info("early_suspend: call handlers\n");
        list_for_each_entry(pos, &early_suspend_handlers, link) {
            if (pos->suspend != NULL)
                pos->suspend(pos);
        }
        mutex_unlock(&early_suspend_lock);
        if (debug_mask & DEBUG_SUSPEND)
            pr_info("early_suspend: sync\n");
        sys_sync();
    abort:
        spin_lock_irqsave(&state_lock, irqflags);
        if (state == SUSPEND_REQUESTED_AND_SUSPENDED)
            wake_unlock(&main_wake_lock);
        spin_unlock_irqrestore(&state_lock, irqflags);
    }



    static void late_resume(struct work_struct *work)
    {
        struct early_suspend *pos;
        unsigned long irqflags;
        int abort = 0;
        mutex_lock(&early_suspend_lock);
        spin_lock_irqsave(&state_lock, irqflags);
        if (state == SUSPENDED)
            state &= ~SUSPENDED;
        else
            abort = 1;
        spin_unlock_irqrestore(&state_lock, irqflags);
        if (abort) {
            if (debug_mask & DEBUG_SUSPEND)
                pr_info("late_resume: abort, state %d\n", state);
            goto abort;
        }
        if (debug_mask & DEBUG_SUSPEND)
            pr_info("late_resume: call handlers\n");
        list_for_each_entry_reverse(pos, &early_suspend_handlers, link)
            if (pos->resume != NULL)
                pos->resume(pos);
        if (debug_mask & DEBUG_SUSPEND)
            pr_info("late_resume: done\n");
    abort:
        mutex_unlock(&early_suspend_lock);
    }




5. 读取suspend state,我估计是这个意思吧。

void request_suspend_state(suspend_state_t new_state)
    {
        unsigned long irqflags;
        int old_sleep;
        spin_lock_irqsave(&state_lock, irqflags);
        old_sleep = state & SUSPEND_REQUESTED;
        if (debug_mask & DEBUG_USER_STATE) {
            struct timespec ts;
            struct rtc_time tm;
            getnstimeofday(&ts);
            rtc_time_to_tm(ts.tv_sec, &tm);
            pr_info("request_suspend_state: %s (%d->%d) at %lld "
                "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
                new_state != PM_SUSPEND_ON ? "sleep" : "wakeup",
                requested_suspend_state, new_state,
                ktime_to_ns(ktime_get()),
                tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
                tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
        }
        if (!old_sleep && new_state != PM_SUSPEND_ON) {
            state |= SUSPEND_REQUESTED;
            queue_work(suspend_work_queue, &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);
        }
        requested_suspend_state = new_state;
        spin_unlock_irqrestore(&state_lock, irqflags);
    }
    suspend_state_t get_suspend_state(void)
    {
        return requested_suspend_state;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值