设为首页 加入收藏

TOP

Power Management(四)
2014-11-23 21:37:42 来源: 作者: 【 】 浏览:61
Tags:Power Management
ile (!error && !wakeup
&& suspend_ops->suspend_again && suspend_ops->suspend_again());

这里是一个死循环。只有wakeup 为1 的时候,我们才会调出这个循环。
我们设备的suspend的时候有很多的操作,每一个操作都放在不同的链表里面,然后我们根据不同suspend的类型,进行不同的操作。
举例如下:
error = dpm_suspend_start(PMSG_SUSPEND);

error = dpm_prepare(state); 会调用到to_device(dpm_list.next); 这个链表 ,这个链表是我们在创建device 的时候,我们所有创建设备的power 控制的结点。遍历过dpm_list 的链表后,我们将设备放到dpm_prepared_list 链表里面,再进行dpm_prepared_list 这个链表的操作。下面的几种状态也是同样的效果,只是不同的操作罢了。

2、设备的注册
我们在注册一个设备的时候,通常会调用device_register 进行设备的注册。下面设备的流程,我们只care power management 部分,别的细节暂时不care 。

整个设备注册的流程:

return device_add(dev); ----》
device_pm_add(dev);-------》

void device_pm_add(struct device *dev)
{
    pr_debug(PM: Adding info for %s:%s
,
         dev->bus   dev->bus->name : No Bus, dev_name(dev));
    mutex_lock(&dpm_list_mtx);
    if (dev->parent && dev->parent->power.is_prepared)
        dev_warn(dev, parent %s should not be sleeping
,
            dev_name(dev->parent));
    list_add_tail(&dev->power.entry, &dpm_list);
    dev_pm_qos_constraints_init(dev);
    mutex_unlock(&dpm_list_mtx);
}


上面的注册会将设备添加到dpm_list里面。 list_add_tail(&dev->power.entry, &dpm_list);
3、suspend_ops 的操作

在整个power management 里面经常会调用到suspend_ops 这个操作集合里面提供的interface 进行
suspend_ops 是存放在kerel/kernel/suspend.c 里面的全部变量。 suspend_set_ops 这个函数会为suspend_set_ops 这个变量进行赋值。
void suspend_set_ops(const struct platform_suspend_ops *ops)
{
lock_system_sleep();
suspend_ops = ops;
unlock_system_sleep();
}

suspend_set_ops 是在/kernel/arch/arm/mach-msm/pm-8x60.c 里面。

static int __init msm_pm_init(void)
{
enum msm_pm_time_stats_id enable_stats[] = {
MSM_PM_STAT_IDLE_WFI,
MSM_PM_STAT_RETENTION,
MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
MSM_PM_STAT_IDLE_POWER_COLLAPSE,
MSM_PM_STAT_SUSPEND,
};
msm_pm_mode_sysfs_add();
msm_pm_add_stats(enable_stats, ARRAY_SIZE(enable_stats));
suspend_set_ops(&msm_pm_ops);


msm_pm_ops 的实现如下:
static const struct platform_suspend_ops msm_pm_ops = {
.enter = msm_pm_enter,
.valid = suspend_valid_only_mem,
.prepare_late = msm_suspend_prepare,
.wake = msm_suspend_wake,
};


看到没有,这个里面实现ops 里面的enter、valid 、prepare_late 、wake 函数。
这些函数在suspend 的时候都会调用到,如:
static int suspend_prepare(void)
{
int error;

if (!suspend_ops || !suspend_ops->enter)
return -EPERM;


这里就在调用enter 函数。

4.设备resume 的流程

当我们按下power key 之后,我们的设备会进入suspend ,整个流程如上面讲解suspend 的流程一样。
source code :


do {
error = suspend_enter(state, &wakeup);
} while (!error && !wakeup
&& suspend_ops->suspend_again && suspend_ops->suspend_again());

suspend_enter 函数的实现:

static int suspend_enter(suspend_state_t state, bool *wakeup)
{
    int error;

    if (suspend_ops->prepare) {
        error = suspend_ops->prepare();
        if (error)
            goto Platform_finish;
    }

    error = dpm_suspend_end(PMSG_SUSPEND);
    if (error) {
        printk(KERN_ERR PM: Some devices failed to power down
);
        goto Platform_finish;
    }

    if (suspend_ops->prepare_late) {
        error = suspend_ops->prepare_late();
        if (error)
            goto Platform_wake;
    }

    if (suspend_test(TEST_PLATFORM))
        goto Platform_wake;

    error = disable_nonboot_cpus();
    if (error || suspend_test(TEST_CPUS))
        goto Enable_cpus;

    arch_suspend_disable_irqs();
    BUG_ON(!irqs_disabled());

    error = syscore_suspend();
    if (!error) {
        *wakeup = pm_wakeup_pending();
        if (!(suspend_test(TEST_CORE) || *wakeup)) {
            er
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言 十进制转换成二进制转换方.. 下一篇数组nice to see you again

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: