summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/dwc3-omap.c
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2016-05-11 17:36:42 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-06-20 12:32:46 +0300
commit3f586c92d87778bc3d550435a31f8ac685541121 (patch)
tree92b7f26825bc3ce9f8ccda665b6f0b6d80e4cf3b /drivers/usb/dwc3/dwc3-omap.c
parent475c8beb35e129c2f33182f476373db04008892e (diff)
downloadlinux-3f586c92d87778bc3d550435a31f8ac685541121.tar.gz
linux-3f586c92d87778bc3d550435a31f8ac685541121.tar.bz2
linux-3f586c92d87778bc3d550435a31f8ac685541121.zip
usb: dwc3: omap: use request_threaded_irq()
We intend to share this interrupt with the OTG driver an to ensure that irqflags match for the shared interrupt handlers we use request_threaded_irq() If we don't use request_treaded_irq() then forced threaded irq will set IRQF_ONESHOT and this won't match with the OTG IRQ handler's IRQ flags. NOTE: OTG IRQ handler is yet to be added. This is a preparatory step. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc3/dwc3-omap.c')
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index af264493bbae..0142544d061f 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -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, 0,
+ "dwc3-omap", omap);
if (ret) {
dev_err(dev, "failed to request IRQ #%d --> %d\n",
omap->irq, ret);