用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) |