[PATCH V2 1/2] USB: musb: gadget: add missed pm_runtime ops to avoid oops

Zumeng Chen zumeng.chen at windriver.com
Thu Jul 26 18:21:48 EDT 2012


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 at 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 at windriver.com>
---
 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




More information about the linux-arm-kernel mailing list