From 04608c2f9082595413cf5f10cddb3eca5eb24105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=BCller?= Date: Sat, 16 Nov 2019 12:32:07 +0100 Subject: [PATCH] Fix USB/FIQ lock-ups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What I did - no rocket science [1]: * Applied RT-patches 4.19.72-rt26 on top of rpi-4.19.y / 4.19.79 (most recent version applying rt-patch properly) * Applied a slightly rebased version of the original (4.14) fiq-patch [2] * grepped for 'fiq_fsm_spin_lock(' and 'fiq_fsm_spin_unlock(' and added missing rt-specific replacements * rebased changes back to rpi-4.19.y-rt What this patch does: * add one missing pair of fiq_fsm_spin_lock/fiq_fsm_spin_unlock replacements With builds of [1] Rapsi3 is running without a singe issue for two weeks now and it was stressed by * moving gigabytes from USB-Stick to SDCard * several usb-midi-keyboard jam sessions Addresses [3] [1] https://github.com/schnitzeltony/meta-raspi-light/tree/master/recipes-kernel/linux [2] https://github.com/raspberrypi/linux/commit/05dd5c4368b56661786da5822d745818d8545d58 [3] https://github.com/raspberrypi/linux/issues/2943 Signed-off-by: Andreas Müller --- drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c index 799ab14b9edadd..c51af872260c25 100644 --- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c @@ -1336,6 +1336,7 @@ static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gin #ifdef CONFIG_USB_DWC_OTG_LPM gintmsk_common.b.lpmtranrcvd = 1; #endif + unsigned long flags; gintmsk_common.b.restoredone = 1; if(dwc_otg_is_device_mode(core_if)) { @@ -1345,8 +1346,7 @@ static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gin gintmsk_common.b.portintr = 1; } if(fiq_enable) { - local_fiq_disable(); - fiq_fsm_spin_lock(&hcd->fiq_state->lock); + fiq_fsm_spin_lock_irqsave(&hcd->fiq_state->lock, flags); gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); /* Pull in the interrupts that the FIQ has masked */ @@ -1354,8 +1354,7 @@ static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gin gintmsk.d32 |= gintmsk_common.d32; /* for the upstairs function to reenable - have to read it here in case FIQ triggers again */ reenable_gintmsk->d32 = gintmsk.d32; - fiq_fsm_spin_unlock(&hcd->fiq_state->lock); - local_fiq_enable(); + fiq_fsm_spin_unlock_irqrestore(&hcd->fiq_state->lock, flags); } else { gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);