Hi Felipe May I suggest ? > we don't need to enable IRQs until we have > a gadget driver loaded and ready to work, > so let's delay IRQ enable to ->udc_start() > and IRQ disable to ->udc_stop(). > > While at that, also move the related use of > request_irq() and free_irq(). How about using devm_request_irq() instead of request_irq() ? Then, free_irq() is not needed > Signed-off-by: Felipe Balbi <balbi@xxxxxx> > --- > drivers/usb/dwc3/gadget.c | 78 ++++++++++++++++++++++++++--------------------- > 1 file changed, 44 insertions(+), 34 deletions(-) > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index f42d02f..d8e963f 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -1469,6 +1469,32 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) > return ret; > } > > +static void dwc3_gadget_enable_irq(struct dwc3 *dwc) > +{ > + u32 reg; > + > + /* Enable all but Start and End of Frame IRQs */ > + reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | > + DWC3_DEVTEN_EVNTOVERFLOWEN | > + DWC3_DEVTEN_CMDCMPLTEN | > + DWC3_DEVTEN_ERRTICERREN | > + DWC3_DEVTEN_WKUPEVTEN | > + DWC3_DEVTEN_ULSTCNGEN | > + DWC3_DEVTEN_CONNECTDONEEN | > + DWC3_DEVTEN_USBRSTEN | > + DWC3_DEVTEN_DISCONNEVTEN); > + > + dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); > +} > + > +static void dwc3_gadget_disable_irq(struct dwc3 *dwc) > +{ > + /* mask all interrupts */ > + dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); > +} > + > +static irqreturn_t dwc3_interrupt(int irq, void *_dwc); > + > static int dwc3_gadget_start(struct usb_gadget *g, > struct usb_gadget_driver *driver) > { > @@ -1476,6 +1502,7 @@ static int dwc3_gadget_start(struct usb_gadget *g, > struct dwc3_ep *dep; > unsigned long flags; > int ret = 0; > + int irq; > u32 reg; > > spin_lock_irqsave(&dwc->lock, flags); > @@ -1536,6 +1563,17 @@ static int dwc3_gadget_start(struct usb_gadget *g, > dwc->ep0state = EP0_SETUP_PHASE; > dwc3_ep0_out_start(dwc); > > + irq = platform_get_irq(to_platform_device(dwc->dev), 0); > + ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, > + "dwc3", dwc); > + if (ret) { > + dev_err(dwc->dev, "failed to request irq #%d --> %d\n", > + irq, ret); > + goto err1; > + } > + > + dwc3_gadget_enable_irq(dwc); > + > spin_unlock_irqrestore(&dwc->lock, flags); > > return 0; > @@ -1554,9 +1592,14 @@ static int dwc3_gadget_stop(struct usb_gadget *g, > { > struct dwc3 *dwc = gadget_to_dwc(g); > unsigned long flags; > + int irq; > > spin_lock_irqsave(&dwc->lock, flags); > > + dwc3_gadget_disable_irq(dwc); > + irq = platform_get_irq(to_platform_device(dwc->dev), 0); > + free_irq(irq, dwc); > + > __dwc3_gadget_ep_disable(dwc->eps[0]); > __dwc3_gadget_ep_disable(dwc->eps[1]); > > @@ -2378,7 +2421,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) > { > u32 reg; > int ret; > - int irq; > > dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req), > &dwc->ctrl_req_addr, GFP_KERNEL); > @@ -2434,32 +2476,10 @@ int dwc3_gadget_init(struct dwc3 *dwc) > if (ret) > goto err4; > > - irq = platform_get_irq(to_platform_device(dwc->dev), 0); > - > - ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, > - "dwc3", dwc); > - if (ret) { > - dev_err(dwc->dev, "failed to request irq #%d --> %d\n", > - irq, ret); > - goto err5; > - } > - > reg = dwc3_readl(dwc->regs, DWC3_DCFG); > reg |= DWC3_DCFG_LPM_CAP; > dwc3_writel(dwc->regs, DWC3_DCFG, reg); > > - /* Enable all but Start and End of Frame IRQs */ > - reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | > - DWC3_DEVTEN_EVNTOVERFLOWEN | > - DWC3_DEVTEN_CMDCMPLTEN | > - DWC3_DEVTEN_ERRTICERREN | > - DWC3_DEVTEN_WKUPEVTEN | > - DWC3_DEVTEN_ULSTCNGEN | > - DWC3_DEVTEN_CONNECTDONEEN | > - DWC3_DEVTEN_USBRSTEN | > - DWC3_DEVTEN_DISCONNEVTEN); > - dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); > - > /* Enable USB2 LPM and automatic phy suspend only on recent versions */ > if (dwc->revision >= DWC3_REVISION_194A) { > reg = dwc3_readl(dwc->regs, DWC3_DCFG); > @@ -2481,15 +2501,11 @@ int dwc3_gadget_init(struct dwc3 *dwc) > ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); > if (ret) { > dev_err(dwc->dev, "failed to register udc\n"); > - goto err6; > + goto err5; > } > > return 0; > > -err6: > - dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); > - free_irq(irq, dwc); > - > err5: > dwc3_gadget_free_endpoints(dwc); > > @@ -2514,13 +2530,7 @@ err0: > > void dwc3_gadget_exit(struct dwc3 *dwc) > { > - int irq; > - > usb_del_gadget_udc(&dwc->gadget); > - irq = platform_get_irq(to_platform_device(dwc->dev), 0); > - > - dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); > - free_irq(irq, dwc); > > dwc3_gadget_free_endpoints(dwc); > > -- > 1.8.1.rc1.5.g7e0651a > > -- > 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 Best regards --- Kuninori Morimoto -- 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