From efb54d0f0445f3d279a7eae7395b566c96d080de Mon Sep 17 00:00:00 2001 From: Phil Elwell 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 --- 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;