Skip to content

Commit

Permalink
usb: dwc3: gadget: introduce and use enable/disable irq methods
Browse files Browse the repository at this point in the history
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().

Tested-by: Vivek Gautam <gautam.vivek@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Felipe Balbi committed Mar 18, 2013
1 parent f122d33 commit 8698e2a
Showing 1 changed file with 45 additions and 35 deletions.
80 changes: 45 additions & 35 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1469,13 +1469,40 @@ 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)
{
struct dwc3 *dwc = gadget_to_dwc(g);
struct dwc3_ep *dep;
unsigned long flags;
int ret = 0;
int irq;
u32 reg;

spin_lock_irqsave(&dwc->lock, flags);
Expand Down Expand Up @@ -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;
Expand All @@ -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]);

Expand Down Expand Up @@ -2454,7 +2497,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);
Expand Down Expand Up @@ -2510,33 +2552,11 @@ 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);

/* automatic phy suspend only on recent versions */
/* Enable USB2 LPM and automatic phy suspend only on recent versions */
if (dwc->revision >= DWC3_REVISION_194A) {
dwc3_gadget_usb2_phy_suspend(dwc, false);
dwc3_gadget_usb3_phy_suspend(dwc, false);
Expand All @@ -2545,15 +2565,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);

Expand All @@ -2578,13 +2594,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)

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);

Expand Down

0 comments on commit 8698e2a

Please sign in to comment.