From 3f2358d458e9190fe62bf107c3beb4642f2c1722 Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 13 Nov 2019 15:52:18 +0800 Subject: [PATCH] usb: dwc3: gadget: avoid multiple calls to free_irq When we use /sys/class/udc//soft_connect to do a logical disconnection from the USB Host on RK3399 Excavator Board, it dumps the warning log: Trying to free already-free IRQ 231 WARNING: CPU: 2 PID: 1308 at kernel/irq/manage.c:1628 __free_irq+0xa0/0x2e0 Modules linked in: CPU: 2 PID: 1308 Comm: adbd Not tainted 4.19.80 #49 Hardware name: Rockchip RK3399 Excavator Board edp avb (Android) (DT) pstate: 40400085 (nZcv daIf +PAN -UAO) pc : __free_irq+0xa0/0x2e0 lr : __free_irq+0xa0/0x2e0 ... Call trace: __free_irq+0xa0/0x2e0 free_irq+0x38/0x90 dwc3_gadget_stop+0x58/0x80 usb_gadget_remove_driver+0x50/0x70 usb_gadget_unregister_driver+0xc0/0x110 unregister_gadget+0x20/0x50 unregister_gadget_item+0x24/0x38 ffs_data_clear+0x120/0x130 ffs_data_reset+0x14/0x50 ffs_data_closed+0x88/0xd8 ffs_epfile_release+0x20/0x30 To solve the problem, don't call free_irq() in dwc3_gadget_stop() if dwc->gadget_driver is NULL. Change-Id: I9d5b5b354612c3ce3677b3d15cf6af1fcbf3f399 Signed-off-by: William Wu --- drivers/usb/dwc3/gadget.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1f41b05e26b8..4c7d05e99887 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2050,17 +2050,25 @@ static int dwc3_gadget_stop(struct usb_gadget *g) spin_lock_irqsave(&dwc->lock, flags); + if (!dwc->gadget_driver) { + spin_unlock_irqrestore(&dwc->lock, flags); + dev_warn(dwc->dev, "%s is already stopped\n", + dwc->gadget.name); + goto out0; + } + if (pm_runtime_suspended(dwc->dev)) - goto out; + goto out1; __dwc3_gadget_stop(dwc); -out: +out1: dwc->gadget_driver = NULL; spin_unlock_irqrestore(&dwc->lock, flags); free_irq(dwc->irq_gadget, dwc->ev_buf); +out0: return 0; }