aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch')
-rw-r--r--target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch157
1 files changed, 157 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch b/target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch
new file mode 100644
index 0000000000..ba021f1e22
--- /dev/null
+++ b/target/linux/bcm27xx/patches-4.19/950-0428-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch
@@ -0,0 +1,157 @@
+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;