Files
openwrt-master/target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch
domenico c06fb25d1f
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
Initial commit
2025-06-24 14:35:53 +02:00

68 lines
2.1 KiB
Diff

From 0b04c37a1aae523025195c29a6477cf26234d26c Mon Sep 17 00:00:00 2001
From: Chuanhong Guo <gch981213@gmail.com>
Date: Tue, 10 Sep 2024 09:10:27 +0800
Subject: [PATCH 9/9] usb: dwc2: handle OTG interrupt regardless of GINTSTS
The DWC OTG 3.30a found on Siflower SF19A2890 has battery charger
support enabled. It triggers MultVallpChng interrupt (bit 20 of
GOTGINT) but doesn't set OTGInt in GINTSTS. As a result, this
interrupt is never handled, and linux disables USB interrupt
because "nobody cares".
Handle OTG interrupt in IRQ handler regardless of whether the
OTGInt bit in GINTSTS is set or not.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
drivers/usb/dwc2/core_intr.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -79,7 +79,7 @@ static void dwc2_handle_mode_mismatch_in
*
* @hsotg: Programming view of DWC_otg controller
*/
-static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
+static irqreturn_t dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
{
u32 gotgint;
u32 gotgctl;
@@ -87,6 +87,10 @@ static void dwc2_handle_otg_intr(struct
gotgint = dwc2_readl(hsotg, GOTGINT);
gotgctl = dwc2_readl(hsotg, GOTGCTL);
+
+ if (!gotgint)
+ return IRQ_NONE;
+
dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
dwc2_op_state_str(hsotg));
@@ -229,6 +233,7 @@ static void dwc2_handle_otg_intr(struct
/* Clear GOTGINT */
dwc2_writel(hsotg, gotgint, GOTGINT);
+ return IRQ_HANDLED;
}
/**
@@ -842,6 +847,8 @@ irqreturn_t dwc2_handle_common_intr(int
hsotg->frame_number = (dwc2_readl(hsotg, HFNUM)
& HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
+ retval = dwc2_handle_otg_intr(hsotg);
+
gintsts = dwc2_read_common_intr(hsotg);
if (gintsts & ~GINTSTS_PRTINT)
retval = IRQ_HANDLED;
@@ -855,8 +862,6 @@ irqreturn_t dwc2_handle_common_intr(int
if (gintsts & GINTSTS_MODEMIS)
dwc2_handle_mode_mismatch_intr(hsotg);
- if (gintsts & GINTSTS_OTGINT)
- dwc2_handle_otg_intr(hsotg);
if (gintsts & GINTSTS_CONIDSTSCHNG)
dwc2_handle_conn_id_status_change_intr(hsotg);
if (gintsts & GINTSTS_DISCONNINT)