From efb54d0f0445f3d279a7eae7395b566c96d080de Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 7 May 2019 17:23:41 +0100
Subject: [PATCH] usb: dwc_otg: Clean up interrupt claiming code

The FIQ/IRQ interrupt number identification code is scattered through
the dwc_otg driver. Rationalise it, simplifying the code and solving
an existing issue.

See: https://github.com/raspberrypi/linux/issues/2612

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
 drivers/usb/host/dwc_otg/dwc_otg_driver.c    | 18 +++++++++-----
 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 10 +++-----
 drivers/usb/host/dwc_otg/dwc_otg_os_dep.h    |  6 +++++
 drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 26 +++-----------------
 4 files changed, 25 insertions(+), 35 deletions(-)

--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
@@ -624,11 +624,7 @@ static int dwc_otg_driver_remove(
 	 * Free the IRQ
 	 */
 	if (otg_dev->common_irq_installed) {
-#ifdef PLATFORM_INTERFACE
-		free_irq(platform_get_irq(_dev, 0), otg_dev);
-#else
-		free_irq(_dev->irq, otg_dev);
-#endif
+		free_irq(otg_dev->os_dep.irq_num, otg_dev);
         } else {
 		DWC_DEBUGPL(DBG_ANY, "%s: There is no installed irq!\n", __func__);
 		return REM_RETVAL(-ENXIO);
@@ -905,7 +901,9 @@ static int dwc_otg_driver_probe(
 	 */
 
 #if defined(PLATFORM_INTERFACE)
-	devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1);
+	devirq = platform_get_irq_byname(_dev, fiq_enable ? "soft" : "usb");
+	if (devirq < 0)
+	    devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1);
 #else
 	devirq = _dev->irq;
 #endif
@@ -922,6 +920,14 @@ static int dwc_otg_driver_probe(
 	} else {
 		dwc_otg_device->common_irq_installed = 1;
 	}
+	dwc_otg_device->os_dep.irq_num = devirq;
+	dwc_otg_device->os_dep.fiq_num = -EINVAL;
+	if (fiq_enable) {
+		int devfiq = platform_get_irq_byname(_dev, "usb");
+		if (devfiq < 0)
+			devfiq = platform_get_irq(_dev, 1);
+		dwc_otg_device->os_dep.fiq_num = devfiq;
+	}
 
 #ifndef IRQF_TRIGGER_LOW
 #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -492,7 +492,7 @@ static void hcd_init_fiq(void *cookie)
 #endif
 	// Enable FIQ interrupt from USB peripheral
 #ifdef CONFIG_ARM64
-	irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
+	irq = otg_dev->os_dep.fiq_num;
 
 	if (irq < 0) {
 		DWC_ERROR("Can't get SIM-FIQ irq");
@@ -509,7 +509,7 @@ static void hcd_init_fiq(void *cookie)
 	simfiq_irq = irq;
 #else
 #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-	irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
+	irq = otg_dev->os_dep.fiq_num;
 #else
 	irq = INTERRUPT_VC_USB;
 #endif
@@ -626,11 +626,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
 	 * allocates the DMA buffer pool, registers the USB bus, requests the
 	 * IRQ line, and calls hcd_start method.
 	 */
-#ifdef PLATFORM_INTERFACE
-	retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED);
-#else
-	retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED);
-#endif
+	retval = usb_add_hcd(hcd, otg_dev->os_dep.irq_num, IRQF_SHARED);
 	if (retval < 0) {
 		goto error2;
 	}
--- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
+++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
@@ -102,6 +102,12 @@ typedef struct os_dependent {
 	/** Base address for MPHI peripheral */
 	void *mphi_base;
 
+	/** IRQ number (<0 if not valid) */
+	int irq_num;
+
+	/** FIQ number (<0 if not valid) */
+	int fiq_num;
+
 #ifdef LM_INTERFACE
 	struct lm_device *lmdev;
 #elif  defined(PCI_INTERFACE)
--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
@@ -1224,30 +1224,16 @@ int pcd_init(dwc_bus_dev_t *_dev)
 	/*
 	 * Setup interupt handler
 	 */
-#ifdef PLATFORM_INTERFACE
 	DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n",
-                    platform_get_irq(_dev, fiq_enable ? 0 : 1));
-	retval = request_irq(platform_get_irq(_dev, fiq_enable ? 0 : 1), dwc_otg_pcd_irq,
+                    otg_dev->os_dep.irq_num);
+	retval = request_irq(otg_dev->os_dep.irq_num, dwc_otg_pcd_irq,
 			     IRQF_SHARED, gadget_wrapper->gadget.name,
 			     otg_dev->pcd);
 	if (retval != 0) {
-		DWC_ERROR("request of irq%d failed\n",
-                          platform_get_irq(_dev, fiq_enable ? 0 : 1));
+		DWC_ERROR("request of irq%d failed\n", otg_dev->os_dep.irq_num);
 		free_wrapper(gadget_wrapper);
 		return -EBUSY;
 	}
-#else
-	DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n",
-                    _dev->irq);
-	retval = request_irq(_dev->irq, dwc_otg_pcd_irq,
-			     IRQF_SHARED | IRQF_DISABLED,
-			     gadget_wrapper->gadget.name, otg_dev->pcd);
-	if (retval != 0) {
-		DWC_ERROR("request of irq%d failed\n", _dev->irq);
-		free_wrapper(gadget_wrapper);
-		return -EBUSY;
-	}
-#endif
 
 	dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
 
@@ -1267,11 +1253,7 @@ void pcd_remove(dwc_bus_dev_t *_dev)
 	/*
 	 * Free the IRQ
 	 */
-#ifdef PLATFORM_INTERFACE
-	free_irq(platform_get_irq(_dev, 0), pcd);
-#else
-	free_irq(_dev->irq, pcd);
-#endif
+	free_irq(otg_dev->os_dep.irq_num, pcd);
 	dwc_otg_pcd_remove(otg_dev->pcd);
 	free_wrapper(gadget_wrapper);
 	otg_dev->pcd = 0;
