musb_gadget has done pm_runtime_* operations in functions insmod-related, and it is necessary to add them in functions rmmod-related, otherwise the following Oops will be happend after rmmod. root@ti-omap3:~# rmmod g_ether Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa0ab006 Internal error: : 1028 [#1] PREEMPT ARM Modules linked in: g_ether(-) CPU: 0 Not tainted (3.4.6) PC is at musb_gadget_disable+0x54/0xd0 LR is at 0x1 pc : [<c0462074>] lr : [<00000001>] psr: 200f0093 sp : c6473e58 ip : fa0ab000 fp : c6473e7c r10: 00000000 r9 : c6472000 r8 : fa0ab110 r7 : 00000001 r6 : 600f0093 r5 : c7414100 r4 : c7414450 r3 : 00000001 r2 : 00000001 r1 : 00000000 r0 : 00000001 Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: 86474019 DAC: 00000015 Process rmmod (pid: 573, stack limit = 0xc64722e8) Stack: (0xc6473e58 to 0xc6474000) 3e40: 00000001 c6c3d480 3e60: c6d36180 00000000 c0462020 c000e9e8 c6473eac c6473e80 bf00647c c046202c 3e80: c6c3d480 c6d36180 c64f2340 00000000 bec70c80 c000e9e8 c6472000 00000000 3ea0: c6473ebc c6473eb0 bf0066a0 bf006424 c6473edc c6473ec0 bf000124 bf006684 3ec0: bf0083c8 c64f2340 a00f0013 c6472000 c6473ef4 c6473ee0 bf001a18 bf0000ec 3ee0: c7776800 c0914914 c6473f0c c6473ef8 c04661ec bf0019e0 c7776968 00000000 3f00: c6473f24 c6473f10 c04662c8 c04661a8 bf008578 00000000 c6473f34 c6473f28 3f20: bf0034f0 c0466264 c6473f44 c6473f38 bf006c58 bf0034cc c6473fa4 c6473f48 3f40: c0086ec4 bf006c50 c6472000 74655f67 00726568 c6473f60 c0060a00 c035dfbc 3f60: c6473f8c c6473f70 c01020d8 c00609f4 b6fde000 00001000 00000000 0000005b 3f80: c6473fa4 00473f90 00000880 00000002 bec70c80 00000081 00000000 c6473fa8 3fa0: c000e780 c0086d3c 00000880 00000002 bec70c80 00000880 bec70c6c 00000000 3fc0: 00000880 00000002 bec70c80 00000081 bec70e08 00000800 bec70c80 bec70cb4 3fe0: 00011e68 bec70c74 00008c60 49c1223c 600f0010 bec70c80 87afe821 87afec21 [<c0462074>] (musb_gadget_disable+0x54/0xd0) from [<bf00647c>] (gether_disconnect+0x64/0x260 [g_ether]) [<bf00647c>] (gether_disconnect+0x64/0x260 [g_ether]) from [<bf0066a0>] (eem_disable+0x28/0x2c [g_ether]) [<bf0066a0>] (eem_disable+0x28/0x2c [g_ether]) from [<bf000124>] (reset_config+0x44/0x6c [g_ether]) [<bf000124>] (reset_config+0x44/0x6c [g_ether]) from [<bf001a18>] (composite_disconnect+0x44/0x90 [g_ether]) [<bf001a18>] (composite_disconnect+0x44/0x90 [g_ether]) from [<c04661ec>] (usb_gadget_remove_driver+0x50/0xbc) [<c04661ec>] (usb_gadget_remove_driver+0x50/0xbc) from [<c04662c8>] (usb_gadget_unregister_driver+0x70/0x94) [<c04662c8>] (usb_gadget_unregister_driver+0x70/0x94) from [<bf0034f0>] (usb_composite_unregister+0x30/0x38 [g_ether]) [<bf0034f0>] (usb_composite_unregister+0x30/0x38 [g_ether]) from [<bf006c58>] (cleanup+0x14/0x1c [g_ether]) [<bf006c58>] (cleanup+0x14/0x1c [g_ether]) from [<c0086ec4>] (sys_delete_module+0x194/0x258) [<c0086ec4>] (sys_delete_module+0x194/0x258) from [<c000e780>] (ret_fast_syscall+0x0/0x30) Code: 0a000018 e595c234 e3a0e001 e3a01000 (e1dc20b6) Signed-off-by: Zumeng Chen <zumeng.chen@xxxxxxxxxxxxx> --- drivers/usb/musb/musb_gadget.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 95918da..adfdf85 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1215,6 +1215,7 @@ static int musb_gadget_disable(struct usb_ep *ep) epnum = musb_ep->current_epnum; epio = musb->endpoints[epnum].regs; + pm_runtime_get_sync(musb->controller); spin_lock_irqsave(&musb->lock, flags); musb_ep_select(musb->mregs, epnum); @@ -1237,9 +1238,10 @@ static int musb_gadget_disable(struct usb_ep *ep) /* abort all pending DMA and requests */ nuke(musb_ep, -ESHUTDOWN); - schedule_work(&musb->irq_work); - spin_unlock_irqrestore(&(musb->lock), flags); + pm_runtime_put(musb->controller); + + schedule_work(&musb->irq_work); dev_dbg(musb->controller, "%s\n", musb_ep->end_point.name); @@ -1296,7 +1298,10 @@ void musb_ep_restart(struct musb *musb, struct musb_request *req) req->tx ? "TX/IN" : "RX/OUT", &req->request, req->request.length, req->epnum); + pm_runtime_get_sync(musb->controller); musb_ep_select(musb->mregs, req->epnum); + pm_runtime_put(musb->controller); + if (req->tx) txstate(musb, req); else @@ -1545,6 +1550,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) unsigned long flags; u16 csr, int_txe; + pm_runtime_get_sync(musb->controller); mbase = musb->mregs; spin_lock_irqsave(&musb->lock, flags); @@ -1578,6 +1584,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) /* re-enable interrupt */ musb_writew(mbase, MUSB_INTRTXE, int_txe); spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_put(musb->controller); } static const struct usb_ep_ops musb_ep_ops = { -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html