diff options
author | Vikram Pandita <vikram.pandita@ti.com> | 2011-08-10 13:59:06 -0700 |
---|---|---|
committer | Dan Murphy <dmurphy@ti.com> | 2011-08-16 14:35:59 -0500 |
commit | 5ada9e23694fafc634d1b0e031758744822da86f (patch) | |
tree | 7858652c6ff8ad3801381e46f2ad0d2bc05cd083 /drivers/usb | |
parent | 20ac708c6ac9d9e624dae55078e824223dc5c29c (diff) | |
download | kernel_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.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 14 |
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"); |