其他分享
首页 > 其他分享> > apm-emulation driver

apm-emulation driver

作者:互联网

apm-emulation driver

在suspend_prepare()里会call error = __pm_notifier_call_chain(PM_SUSPEND_PREPARE, -1, &nr_calls);

因为apm-emulation有注册关于此的callback func,所以会call到apm_suspend_notifier,在此函数里,将会发一个apm_event_t类型的event APM_USER_SUSPEND(通过queue_add_event),然后wakeup apm_waitqueue,userspace如果有进程来read此event,将会读到此event,然后返回,userspace read系统调用会走到apm_read(),这是一个阻塞系统调用,没有event将会阻塞,有event读到event后返回。

 

drivers/char/apm-emulation.c

static int apm_suspend_notifier(struct notifier_block *nb,
                unsigned long event,
                void *dummy)
{
    struct apm_user *as;
    int err;
    unsigned long apm_event;

    /* short-cut emergency suspends */
    if (atomic_read(&userspace_notification_inhibit))
        return NOTIFY_DONE;

    switch (event) {
    case PM_SUSPEND_PREPARE:
    case PM_HIBERNATION_PREPARE:
        apm_event = (event == PM_SUSPEND_PREPARE) ?
            APM_USER_SUSPEND : APM_USER_HIBERNATION;
        /*
         * Queue an event to all "writer" users that we want
         * to suspend and need their ack.
         */
        mutex_lock(&state_lock);
        down_read(&user_list_lock);

        list_for_each_entry(as, &apm_user_list, list) {
            if (as->suspend_state != SUSPEND_WAIT && as->reader &&
                as->writer && as->suser) {
                as->suspend_state = SUSPEND_PENDING;
                atomic_inc(&suspend_acks_pending);
                queue_add_event(&as->queue, apm_event);
            }
        }

        up_read(&user_list_lock);
        mutex_unlock(&state_lock);
        wake_up_interruptible(&apm_waitqueue);

        /*
         * Wait for the the suspend_acks_pending variable to drop to
         * zero, meaning everybody acked the suspend event (or the
         * process was killed.)
         *
         * If the app won't answer within a short while we assume it
         * locked up and ignore it.
         */
        err = wait_event_interruptible_timeout(
            apm_suspend_waitqueue,
            atomic_read(&suspend_acks_pending) == 0,
            5*HZ);

 

标签:suspend,read,list,driver,SUSPEND,emulation,apm,event
来源: https://www.cnblogs.com/aspirs/p/15406162.html