openwrt/target/linux/siflower/patches-6.6/009-usb-dwc2-handle-OTG-interrupt-regardless-of-GINTSTS.patch
Chuanhong Guo 4ed209326b siflower: new target for Siflower SF19A2890
Siflower SF19A2890 is an SoC with:
Dual-core MIPS InterAptiv at 800MHz
DDR3 controller
One Gigabit Ethernet MAC with RGMII and IPv4 HNAT engine
Built-in 2x2 11N + 2x2 11AC WiFi radio
USB 2.0 OTG
I2C/SPI/GPIO and various other peripherals

This PR adds support for SF19A2890 EVB with ethernet support.

EVB spec:
Memory: DDR3 128M
Ethernet: RTL8367RB 5-port gigabit switch
Flash: 16M NOR
Others: MicroUSB OTG, LED x 1, Reset button x1

The built image can be flashed using u-boot recovery.

This target is marked as source-only until support for a commercial
router board comes.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2024-09-17 22:16:41 +08: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)