Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65465
  • 博文数量: 26
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 17
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-28 18:56
文章分类
文章存档

2014年(9)

2013年(17)

我的朋友

分类: LINUX

2013-04-23 20:26:16

用WARN_ON(1)分析otg runtime suspend/resume的整个流程。
在需要跟踪流程的代码内加上WARN_ON(1),通过打印的WARNING,回溯栈跟踪代码流程。
/*下面是在设备拔出的时候,加入WARN_ON(1)时打出的回溯栈*/
[   28.608405] ------------[ cut here ]------------
[   28.611998] WARNING: at drivers/usb/otg/msm72k_otg.c:809 msm_otg_runtime_suspend+0x49c/0x500()
[   28.635294] Modules linked in:
[   28.637328] [] (unwind_backtrace+0x0/0x12c) from [] (warn_slowpath_common+0x4c/0x64)
[   28.655305] [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_null+0x18/0x1c)
[   28.663926] [] (warn_slowpath_null+0x18/0x1c) from [] (msm_otg_runtime_suspend+0x49c/0x500)
[   28.695309] [] (msm_otg_runtime_suspend+0x49c/0x500) from [] (pm_generic_runtime_suspend+0x2c/0x38)
[   28.705059] [] (pm_generic_runtime_suspend+0x2c/0x38) from [] (rpm_callback+0x88/0xe0)
[   28.735304] [] (rpm_callback+0x88/0xe0) from [] (rpm_suspend+0x2ec/0x5f8)
[   28.742795] [] (rpm_suspend+0x2ec/0x5f8) from [] (__pm_runtime_suspend+0xc8/0x128)
[   28.765302] [] (__pm_runtime_suspend+0xc8/0x128) from [] (pm_generic_runtime_idle+0x44/0x4c)
[   28.774442] [] (pm_generic_runtime_idle+0x44/0x4c) from [] (rpm_idle+0x170/0x1f4)
[   28.805303] [] (rpm_idle+0x170/0x1f4) from [] (__pm_runtime_idle+0xb4/0x114)
[   28.813056] [] (__pm_runtime_idle+0xb4/0x114) from [] (msm_otg_put_suspend+0x14/0x30)
[   28.835305] [] (msm_otg_put_suspend+0x14/0x30) from [] (msm_otg_sm_work+0x7a0/0x2708)
[   28.843845] [] (msm_otg_sm_work+0x7a0/0x2708) from [] (process_one_work+0x2c8/0x4cc)
[   28.875315] [] (process_one_work+0x2c8/0x4cc) from [] (worker_thread+0x2b8/0x460)
[   28.883505] [] (worker_thread+0x2b8/0x460) from [] (kthread+0x80/0x88)
[   28.905311] [] (kthread+0x80/0x88) from [] (kernel_thread_exit+0x0/0x8)
[   28.912621] ---[ end trace 1b75b31a2719ed23 ]---
[   28.935299] msm_otg_suspend: usb in low power mode
[   31.664486] tsens_tz_set_mode: mode: 0 --> 1
[   66.177216] battery capacity very low = 4

/*下面是在设备插入的时候,加入WARN_ON(1)时打出的回溯栈*/
[  213.632129] WARNING: at drivers/usb/otg/msm72k_otg.c:861 msm_otg_runtime_resume+0x13c/0x174()
[  213.640645] Modules linked in:
[  213.643672] [] (unwind_backtrace+0x0/0x12c) from [] (warn_slowpath_common+0x4c/0x64)
[  213.653132] [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_null+0x18/0x1c)
[  213.662766] [] (warn_slowpath_null+0x18/0x1c) from [] (msm_otg_runtime_resume+0x13c/0x174)
[  213.672751] [] (msm_otg_runtime_resume+0x13c/0x174) from [] (pm_generic_runtime_resume+0x2c/0x38)
[  213.683340] [] (pm_generic_runtime_resume+0x2c/0x38) from [] (rpm_callback+0x88/0xe0)
[  213.692911] [] (rpm_callback+0x88/0xe0) from [] (rpm_resume+0x558/0x784)
[  213.701309] [] (rpm_resume+0x558/0x784) from [] (__pm_runtime_resume+0xb4/0x114)
[  213.710423] [] (__pm_runtime_resume+0xb4/0x114) from [] (msm_otg_set_suspend+0x334/0x46c)
[  213.720316] [] (msm_otg_set_suspend+0x334/0x46c) from [] (msm_otg_sm_work+0x34/0x2708)
[  213.729958] [] (msm_otg_sm_work+0x34/0x2708) from [] (process_one_work+0x2c8/0x4cc)
[  213.739348] [] (process_one_work+0x2c8/0x4cc) from [] (worker_thread+0x2a4/0x460)
[  213.748534] [] (worker_thread+0x2a4/0x460) from [] (kthread+0x80/0x88)
[  213.756781] [] (kthread+0x80/0x88) from [] (kernel_thread_exit+0x0/0x8)
[  213.765098] ---[ end trace 1b75b31a2719ed24 ]---
[  213.769700] msm_otg_resume: usb exited from low power mode

/*otg设备runtime suspend的整个流程*/
//Msm72k_otg.c (drivers\usb\otg)
static void msm_otg_sm_work(struct work_struct *w)
{
    ..............
    case OTG_STATE_B_IDLE:
        dev->otg.default_a = 0;
        ..........
        } else {
            msm_otg_set_power(&dev->otg, 0);
            pr_info("%s: -->>entering into lpm.\n",__func__);
            msm_otg_put_suspend(dev);

            if (dev->pdata->ldo_set_voltage)
                dev->pdata->ldo_set_voltage(3075);
        }
        break;
    .......................
}
static void msm_otg_put_suspend(struct msm_otg *dev)
{
    ...........
    pm_runtime_put_sync(dev->otg.dev);
    ...............
}

//Pm_runtime.h (include\linux)
static inline int pm_runtime_put_sync(struct device *dev)
{
    return __pm_runtime_idle(dev, RPM_GET_PUT);
}

int __pm_runtime_idle(struct device *dev, int rpmflags)
{
    .............
    retval = rpm_idle(dev, rpmflags);
    ....................
}

//Runtime.c (drivers\base\power)
static int rpm_idle(struct device *dev, int rpmflags)
{
    ....................
    int (*callback)(struct device *);
    if (dev->bus && dev->bus->pm)//调用bus的runtime_idle函数
        callback = dev->bus->pm->runtime_idle;
    if (callback) {
        ...........
        callback(dev);
        ................
    }
    ..................
}

/*bus的runtime结构体定义如下*/
//Platform.c (drivers\base)
static const struct dev_pm_ops platform_dev_pm_ops = {
    .runtime_suspend = pm_generic_runtime_suspend,
    .runtime_resume = pm_generic_runtime_resume,
    .runtime_idle = pm_generic_runtime_idle,
    USE_PLATFORM_PM_SLEEP_OPS
};

struct bus_type platform_bus_type = {
    .name        = "platform",
    .dev_attrs    = platform_dev_attrs,
    .match        = platform_match,
    .uevent    = platform_uevent,
    .pm        = &platform_dev_pm_ops,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

//Generic_ops.c (drivers\base\power)
int pm_generic_runtime_idle(struct device *dev)
{
    const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

    if (pm && pm->runtime_idle) { //调用otg结构体的idle函数
        int ret = pm->runtime_idle(dev);
        if (ret)
            return ret;
    }

    pm_runtime_suspend(dev);
    return 0;
}
EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);

//Pm_runtime.h (include\linux)
static inline int pm_runtime_suspend(struct device *dev)
{
    return __pm_runtime_suspend(dev, 0);
}

//Runtime.c (drivers\base\power)
int __pm_runtime_suspend(struct device *dev, int rpmflags)
{
    unsigned long flags;
    int retval;

    might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);

    if (rpmflags & RPM_GET_PUT) {
        if (!atomic_dec_and_test(&dev->power.usage_count))
            return 0;
    }

    spin_lock_irqsave(&dev->power.lock, flags);
    retval = rpm_suspend(dev, rpmflags);
    spin_unlock_irqrestore(&dev->power.lock, flags);

    return retval;
}
EXPORT_SYMBOL_GPL(__pm_runtime_suspend);

static int rpm_suspend(struct device *dev, int rpmflags)
    __releases(&dev->power.lock) __acquires(&dev->power.lock)
{
    int (*callback)(struct device *);
    if (dev->bus && dev->bus->pm)
        callback = dev->bus->pm->runtime_suspend;
    retval = rpm_callback(callback, dev);
    return retval;
}

/*调用bus的suspend函数*/
static int rpm_callback(int (*cb)(struct device *), struct device *dev)
    __releases(&dev->power.lock) __acquires(&dev->power.lock)
{

    if (dev->power.irq_safe) {
        retval = cb(dev);
    } else {

        retval = cb(dev);

    }
    return retval;
}

/*bus的runtime结构体定义如下*/
//Platform.c (drivers\base)
static const struct dev_pm_ops platform_dev_pm_ops = {
    .runtime_suspend = pm_generic_runtime_suspend,
    .runtime_resume = pm_generic_runtime_resume,
    .runtime_idle = pm_generic_runtime_idle,
    USE_PLATFORM_PM_SLEEP_OPS
};

struct bus_type platform_bus_type = {
    .name        = "platform",
    .dev_attrs    = platform_dev_attrs,
    .match        = platform_match,
    .uevent    = platform_uevent,
    .pm        = &platform_dev_pm_ops,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

//Generic_ops.c (drivers\base\power)
int pm_generic_runtime_suspend(struct device *dev)
{
    const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
    int ret;

    ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;

    return ret;
}
EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);

/*调用具体的平台驱动的suspend函数*/
//Msm72k_otg.c (drivers\usb\otg)
static struct dev_pm_ops msm_otg_dev_pm_ops = {
    .runtime_suspend = msm_otg_runtime_suspend,
    .runtime_resume = msm_otg_runtime_resume,
    .runtime_idle = msm_otg_runtime_idle,
};

static struct platform_driver msm_otg_driver = {
    .remove = __exit_p(msm_otg_remove),
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .pm = &msm_otg_dev_pm_ops,
    },
};

static int msm_otg_runtime_suspend(struct device *dev)
{
    struct msm_otg *otg = the_msm_otg;

    dev_dbg(dev, "pm_runtime: suspending...\n");
    msm_otg_suspend(otg);
    return  0;
}


static int msm_otg_suspend(struct msm_otg *dev)
{
    ..................
    if (dev->pdata->pmic_id_notif_init && !host_bus_suspend && !test_bit(ID_A, &dev->inputs)) {
        ..........
        ret = dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 1);//注册回调函数
        if (!ret) {
            dev->pmic_id_notif_supp = 1;
            if (dev->pdata->pmic_id_irq)
                dev->id_irq = dev->pdata->pmic_id_irq;
        }
        ............
    }
    ..................
    atomic_set(&dev->in_lpm, 1);
    .........................
}

/*otg设备,runtime resume的整个流程*/
static void msm_otg_sm_work(struct work_struct *w)
{
    .................
    if (atomic_read(&dev->in_lpm))
    {
        msm_otg_set_suspend(&dev->otg, 0);
    }
}

static int msm_otg_set_suspend(struct otg_transceiver *xceiv, int suspend)
{

    if (suspend) {
        ...............
        ........................
    } else {
        .............
        msm_otg_get_resume(dev);
        ......................
        if (dev->pmic_id_notif_supp) {
            pr_info("%s:--->>I will unregister the id irq and id pin config!!!.\n",__func__);
            dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
            dev->pmic_id_notif_supp = 0;
        }
    }


static void msm_otg_get_resume(struct msm_otg *dev)
{
    ..........
    pm_runtime_resume(dev->otg.dev);
    ..............
}

static inline int pm_runtime_resume(struct device *dev)
{
    return __pm_runtime_resume(dev, 0);
}

int __pm_runtime_resume(struct device *dev, int rpmflags)
{
    ..........
    retval = rpm_resume(dev, rpmflags);
    ................

    return retval;
}
EXPORT_SYMBOL_GPL(__pm_runtime_resume);

static int rpm_resume(struct device *dev, int rpmflags)
    __releases(&dev->power.lock) __acquires(&dev->power.lock)
{
    int (*callback)(struct device *);
    if (dev->bus && dev->bus->pm)
        callback = dev->bus->pm->runtime_resume;

    retval = rpm_callback(callback, dev);
}

/*bus的runtime结构体定义如下*/
//Platform.c (drivers\base)
static const struct dev_pm_ops platform_dev_pm_ops = {
    .runtime_suspend = pm_generic_runtime_suspend,
    .runtime_resume = pm_generic_runtime_resume,
    .runtime_idle = pm_generic_runtime_idle,
    USE_PLATFORM_PM_SLEEP_OPS
};

struct bus_type platform_bus_type = {
    .name        = "platform",
    .dev_attrs    = platform_dev_attrs,
    .match        = platform_match,
    .uevent    = platform_uevent,
    .pm        = &platform_dev_pm_ops,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

/*调用总线的resume函数*/
int pm_generic_runtime_resume(struct device *dev)
{
    const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
    int ret;

    ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;//该函数指向各个模块的resume函数

    return ret;
}
EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);

/*调用otg模块自己的resume函数*/
static int msm_otg_runtime_resume(struct device *dev)
{
    struct msm_otg *otg = the_msm_otg;

    dev_dbg(dev, "pm_runtime: resuming...\n");
    msm_otg_resume(otg);
    return  0;
}

static int msm_otg_resume(struct msm_otg *dev)
{
    ...........
    atomic_set(&dev->in_lpm, 0);
    pr_info("%s: usb exited from low power mode\n", __func__);

    return 0;
}
阅读(1201) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~