usb: dwc3: omap: Mark the interrupt handler as shared
[cascardo/linux.git] / drivers / usb / dwc3 / dwc3-omap.c
index af26449..bde69fc 100644 (file)
@@ -165,7 +165,7 @@ static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
 
 static u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap)
 {
-       return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_0 -
+       return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_0 -
                                                omap->irq0_offset);
 }
 
@@ -178,7 +178,7 @@ static void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value)
 
 static u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap)
 {
-       return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_MISC +
+       return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_MISC +
                                                omap->irqmisc_offset);
 }
 
@@ -268,19 +268,38 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
        }
 }
 
+static void dwc3_omap_enable_irqs(struct dwc3_omap *omap);
+static void dwc3_omap_disable_irqs(struct dwc3_omap *omap);
+
 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
+{
+       struct dwc3_omap        *omap = _omap;
+
+       if (dwc3_omap_read_irqmisc_status(omap) ||
+           dwc3_omap_read_irq0_status(omap)) {
+               /* mask irqs */
+               dwc3_omap_disable_irqs(omap);
+               return IRQ_WAKE_THREAD;
+       }
+
+       return IRQ_NONE;
+}
+
+static irqreturn_t dwc3_omap_interrupt_thread(int irq, void *_omap)
 {
        struct dwc3_omap        *omap = _omap;
        u32                     reg;
 
+       /* clear irq status flags */
        reg = dwc3_omap_read_irqmisc_status(omap);
-
        dwc3_omap_write_irqmisc_status(omap, reg);
 
        reg = dwc3_omap_read_irq0_status(omap);
-
        dwc3_omap_write_irq0_status(omap, reg);
 
+       /* unmask irqs */
+       dwc3_omap_enable_irqs(omap);
+
        return IRQ_HANDLED;
 }
 
@@ -497,8 +516,9 @@ static int dwc3_omap_probe(struct platform_device *pdev)
        /* check the DMA Status */
        reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
 
-       ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0,
-                       "dwc3-omap", omap);
+       ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
+                                       dwc3_omap_interrupt_thread, IRQF_SHARED,
+                                       "dwc3-omap", omap);
        if (ret) {
                dev_err(dev, "failed to request IRQ #%d --> %d\n",
                                omap->irq, ret);