aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorVikram Pandita <vikram.pandita@ti.com>2011-08-10 13:59:06 -0700
committerDan Murphy <dmurphy@ti.com>2011-08-16 14:35:59 -0500
commit5ada9e23694fafc634d1b0e031758744822da86f (patch)
tree7858652c6ff8ad3801381e46f2ad0d2bc05cd083 /drivers/usb
parent20ac708c6ac9d9e624dae55078e824223dc5c29c (diff)
downloadkernel_samsung_tuna-5ada9e23694fafc634d1b0e031758744822da86f.zip
kernel_samsung_tuna-5ada9e23694fafc634d1b0e031758744822da86f.tar.gz
kernel_samsung_tuna-5ada9e23694fafc634d1b0e031758744822da86f.tar.bz2
usb: musb: fix pm_runtime calls while atomic
musb pm_runtime_get_sync call happens in interrupt context on cable attach case That can result in re-enabling the interrupts and cause side affects. So move the code to a work queue. Following is the error path hit on cable attach: Backtrace: [<c00518d0>] (dump_backtrace+0x0/0x10c) from [<c0539ae8>] (dump_stack+0x18/0x1c) [<c0539ad0>] (dump_stack+0x0/0x1c) from [<c007bca8>] (__might_sleep+0x108/0x128) [<c007bba0>] (__might_sleep+0x0/0x128) from [<c027f770>] (__pm_runtime_resume+0x90/0x98) [<c027f6e0>] (__pm_runtime_resume+0x0/0x98) from [<c0327a24>] (musb_otg_notifications+0xd4/0x1f4) [<c0327950>] (musb_otg_notifications+0x0/0x1f4) from [<c00adfc0>] (notifier_call_chain+0x4c/0x8c) [<c00adf74>] (notifier_call_chain+0x0/0x8c) from [<c00ae688>] (__atomic_notifier_call_chain+0x40/0x54) [<c00ae648>] (__atomic_notifier_call_chain+0x0/0x54) from [<c00ae6bc>] (atomic_notifier_call_chain+0x20/0x28) Tested with: MUSB Device mode: Cold boot / Hot plug MUSB Host mode: Cold boot / Hot plug Change-Id: Ia05925a71158271ed4882ba1c95e79ae1371b61f Signed-off-by: Vikram Pandita <vikram.pandita@ti.com> Signed-off-by: Moiz Sonasath <m-sonasath@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/musb_core.h2
-rw-r--r--drivers/usb/musb/omap2430.c14
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f65269d..40a6ceb 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -386,6 +386,7 @@ struct musb {
irqreturn_t (*isr)(int, void *);
struct work_struct irq_work;
+ struct work_struct otg_notifier_work;
u16 hwvers;
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
@@ -432,6 +433,7 @@ struct musb {
u16 int_tx;
struct otg_transceiver *xceiv;
+ u8 xceiv_event;
int nIrq;
unsigned irq_wake:1;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index ac4cfbc..9baec29 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -234,11 +234,21 @@ static int musb_otg_notifications(struct notifier_block *nb,
unsigned long event, void *unused)
{
struct musb *musb = container_of(nb, struct musb, nb);
+
+ musb->xceiv_event = event;
+ schedule_work(&musb->otg_notifier_work);
+
+ return 0;
+}
+
+static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
+{
+ struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work);
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *pdata = dev->platform_data;
struct omap_musb_board_data *data = pdata->board_data;
- switch (event) {
+ switch (musb->xceiv_event) {
case USB_EVENT_ID:
dev_dbg(musb->controller, "ID GND\n");
@@ -322,6 +332,8 @@ static int omap2430_musb_init(struct musb *musb)
return -ENODEV;
}
+ INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
+
status = pm_runtime_get_sync(dev);
if (status < 0) {
dev_err(dev, "pm_runtime_get_sync FAILED");