diff options
author | Vikram Pandita <vikram.pandita@ti.com> | 2011-08-12 10:38:51 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-12-12 04:51:54 -0500 |
commit | 712d8efafbbcbe617f9ad706f6ca1ffea4bbf2e8 (patch) | |
tree | e3178632a7ab3f811b7b8b17f88a80e85fb2515e /drivers/usb/musb/omap2430.c | |
parent | 1e546aa6c4cfe83050fc78487c8aa78b6947006c (diff) |
usb: musb: fix pm_runtime calls while atomic
musb pm_runtime_get_sync call happens in intrrupt 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:
BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:802
in_atomic(): 0, irqs_disabled(): 0, pid: 18, name: irq/378-twl6030
Backtrace:
[<c00520f0>] (dump_backtrace+0x0/0x110) from [<c054f454>] (dump_stack+0x18/0x1c)
[<c054f43c>] (dump_stack+0x0/0x1c) from [<c007f59c>] (__might_sleep+0x130/0x134)
[<c007f46c>] (__might_sleep+0x0/0x134) from [<c02c2794>] (__pm_runtime_resume+0x94/0x98)
[<c02c2700>] (__pm_runtime_resume+0x0/0x98) from [<c033e7e4>] (musb_otg_notifications+0x9c/0x164)
[<c033e748>] (musb_otg_notifications+0x0/0x164) from [<c00b3df0>] (notifier_call_chain+0x4c/0x8c)
[<c00b3da4>] (notifier_call_chain+0x0/0x8c) from [<c00b44a8>] (__atomic_notifier_call_chain+0x40/0x54)
[<c00b4468>] (__atomic_notifier_call_chain+0x0/0x54) from [<c00b44dc>] (atomic_notifier_call_chain+0x20/0x28)
[<c00b44bc>] (atomic_notifier_call_chain+0x0/0x28) from [<c033f124>] (twl6030_usb_irq+0xc8/0xdc)
[<c033f05c>] (twl6030_usb_irq+0x0/0xdc) from [<c00d79f8>] (irq_thread_fn+0x24/0x40)
[<c00d79d4>] (irq_thread_fn+0x0/0x40) from [<c00d7b64>] (irq_thread+0x150/0x1d8)
[<c00d7a14>] (irq_thread+0x0/0x1d8) from [<c00adf70>] (kthread+0x94/0x98)
[<c00adedc>] (kthread+0x0/0x98) from [<c0094388>] (do_exit+0x0/0x720)
Tested with:
MUSB Device mode: Cold boot / Hot plug
MUSB Host mode: Cold boot / Hot plug
Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
Signed-off-by: Moiz Sonasath <m-sonasath@ti.com>
Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r-- | drivers/usb/musb/omap2430.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2f6cd431fb1c..fd5dd46039ad 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -227,11 +227,21 @@ static int musb_otg_notifications(struct notifier_block *nb, | |||
227 | unsigned long event, void *unused) | 227 | unsigned long event, void *unused) |
228 | { | 228 | { |
229 | struct musb *musb = container_of(nb, struct musb, nb); | 229 | struct musb *musb = container_of(nb, struct musb, nb); |
230 | |||
231 | musb->xceiv_event = event; | ||
232 | schedule_work(&musb->otg_notifier_work); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static void musb_otg_notifier_work(struct work_struct *data_notifier_work) | ||
238 | { | ||
239 | struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work); | ||
230 | struct device *dev = musb->controller; | 240 | struct device *dev = musb->controller; |
231 | struct musb_hdrc_platform_data *pdata = dev->platform_data; | 241 | struct musb_hdrc_platform_data *pdata = dev->platform_data; |
232 | struct omap_musb_board_data *data = pdata->board_data; | 242 | struct omap_musb_board_data *data = pdata->board_data; |
233 | 243 | ||
234 | switch (event) { | 244 | switch (musb->xceiv_event) { |
235 | case USB_EVENT_ID: | 245 | case USB_EVENT_ID: |
236 | dev_dbg(musb->controller, "ID GND\n"); | 246 | dev_dbg(musb->controller, "ID GND\n"); |
237 | 247 | ||
@@ -296,6 +306,8 @@ static int omap2430_musb_init(struct musb *musb) | |||
296 | return -ENODEV; | 306 | return -ENODEV; |
297 | } | 307 | } |
298 | 308 | ||
309 | INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work); | ||
310 | |||
299 | status = pm_runtime_get_sync(dev); | 311 | status = pm_runtime_get_sync(dev); |
300 | if (status < 0) { | 312 | if (status < 0) { |
301 | dev_err(dev, "pm_runtime_get_sync FAILED"); | 313 | dev_err(dev, "pm_runtime_get_sync FAILED"); |