Created
April 27, 2025 09:31
-
-
Save lategoodbye/74c25cd234694031362896115e3e4dfd to your computer and use it in GitHub Desktop.
usb: dwc2: Add counter to debugfs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From cd7885dcfcae16cf8208cfe375c9901ba44586a5 Mon Sep 17 00:00:00 2001 | |
From: Stefan Wahren <[email protected]> | |
Date: Sun, 27 Apr 2025 11:22:01 +0200 | |
Subject: [PATCH] usb: dwc2: Add counter to debugfs | |
Signed-off-by: Stefan Wahren <[email protected]> | |
--- | |
drivers/usb/dwc2/core.h | 24 +++++++++++++++++++++ | |
drivers/usb/dwc2/core_intr.c | 42 +++++++++++++++++++++++++++++------- | |
drivers/usb/dwc2/debugfs.c | 39 +++++++++++++++++++++++++++++++++ | |
drivers/usb/dwc2/hcd_intr.c | 31 ++++++++++++++++++++------ | |
4 files changed, 122 insertions(+), 14 deletions(-) | |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h | |
index 34127b890b2a..d37166d30e32 100644 | |
--- a/drivers/usb/dwc2/core.h | |
+++ b/drivers/usb/dwc2/core.h | |
@@ -1105,6 +1105,30 @@ struct dwc2_hsotg { | |
struct debugfs_regset32 *regset; | |
bool needs_byte_swap; | |
+ u32 common_intr; | |
+ u32 gpwrdn_intr; | |
+ u32 mismatch_intr; | |
+ u32 otg_intr; | |
+ u32 conn_id_intr; | |
+ u32 disconnect_intr; | |
+ u32 session_req_intr; | |
+ u32 wakeup_intr; | |
+ u32 suspend_intr; | |
+ u32 lpm_intr; | |
+ u32 device_port_intr; | |
+ u32 host_port_intr; | |
+ u32 unhandled_intr; | |
+ | |
+ u32 hcd_intr; | |
+ u32 hcd_unhandled_intr1; | |
+ u32 hcd_unhandled_intr2; | |
+ u32 hcd_sof_intr; | |
+ u32 hcd_rx_fifo_intr; | |
+ u32 hcd_tx_fifo_intr; | |
+ u32 hcd_port_intr; | |
+ u32 hcd_hc_intr; | |
+ u32 hcd_device_intr; | |
+ | |
/* DWC OTG HW Release versions */ | |
#define DWC2_CORE_REV_4_30a 0x4f54430a | |
#define DWC2_CORE_REV_2_71a 0x4f54271a | |
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c | |
index 7d3e641806f8..42f7d3e11cd6 100644 | |
--- a/drivers/usb/dwc2/core_intr.c | |
+++ b/drivers/usb/dwc2/core_intr.c | |
@@ -849,6 +849,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |
spin_lock(&hsotg->lock); | |
+ hsotg->common_intr++; | |
+ | |
if (!dwc2_is_controller_alive(hsotg)) { | |
dev_warn(hsotg->dev, "Controller is dead\n"); | |
goto out; | |
@@ -869,26 +871,43 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |
/* In case of hibernated state gintsts must not work */ | |
if (hsotg->hibernated) { | |
dwc2_handle_gpwrdn_intr(hsotg); | |
+ hsotg->gpwrdn_intr++; | |
retval = IRQ_HANDLED; | |
goto out; | |
} | |
- if (gintsts & GINTSTS_MODEMIS) | |
+ if (gintsts & GINTSTS_MODEMIS) { | |
dwc2_handle_mode_mismatch_intr(hsotg); | |
- if (gintsts & GINTSTS_OTGINT) | |
+ hsotg->mismatch_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_OTGINT) { | |
dwc2_handle_otg_intr(hsotg); | |
- if (gintsts & GINTSTS_CONIDSTSCHNG) | |
+ hsotg->otg_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_CONIDSTSCHNG) { | |
dwc2_handle_conn_id_status_change_intr(hsotg); | |
- if (gintsts & GINTSTS_DISCONNINT) | |
+ hsotg->conn_id_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_DISCONNINT) { | |
dwc2_handle_disconnect_intr(hsotg); | |
- if (gintsts & GINTSTS_SESSREQINT) | |
+ hsotg->disconnect_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_SESSREQINT) { | |
dwc2_handle_session_req_intr(hsotg); | |
- if (gintsts & GINTSTS_WKUPINT) | |
+ hsotg->session_req_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_WKUPINT) { | |
dwc2_handle_wakeup_detected_intr(hsotg); | |
- if (gintsts & GINTSTS_USBSUSP) | |
+ hsotg->wakeup_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_USBSUSP) { | |
dwc2_handle_usb_suspend_intr(hsotg); | |
- if (gintsts & GINTSTS_LPMTRANRCVD) | |
+ hsotg->suspend_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_LPMTRANRCVD) { | |
dwc2_handle_lpm_intr(hsotg); | |
+ hsotg->lpm_intr++; | |
+ } | |
if (gintsts & GINTSTS_PRTINT) { | |
/* | |
@@ -899,11 +918,18 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |
dev_dbg(hsotg->dev, | |
" --Port interrupt received in Device mode--\n"); | |
dwc2_handle_usb_port_intr(hsotg); | |
+ hsotg->device_port_intr++; | |
retval = IRQ_HANDLED; | |
+ } else { | |
+ if (retval == IRQ_NONE) | |
+ hsotg->host_port_intr++; | |
} | |
} | |
out: | |
+ if (retval == IRQ_NONE) | |
+ hsotg->unhandled_intr++; | |
+ | |
spin_unlock(&hsotg->lock); | |
return retval; | |
} | |
diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c | |
index 3116ac72747f..639aae73f359 100644 | |
--- a/drivers/usb/dwc2/debugfs.c | |
+++ b/drivers/usb/dwc2/debugfs.c | |
@@ -772,6 +772,44 @@ static int dr_mode_show(struct seq_file *seq, void *v) | |
} | |
DEFINE_SHOW_ATTRIBUTE(dr_mode); | |
+#define print_stat(_seq, _ptr, _param) \ | |
+seq_printf((_seq), "%-30s: %u\n", #_param, (_ptr)->_param) | |
+ | |
+static int stats_show(struct seq_file *seq, void *v) | |
+{ | |
+ struct dwc2_hsotg *hsotg = seq->private; | |
+ | |
+ print_stat(seq, hsotg, common_intr); | |
+ print_stat(seq, hsotg, gpwrdn_intr); | |
+ print_stat(seq, hsotg, mismatch_intr); | |
+ print_stat(seq, hsotg, otg_intr); | |
+ print_stat(seq, hsotg, conn_id_intr); | |
+ print_stat(seq, hsotg, disconnect_intr); | |
+ print_stat(seq, hsotg, session_req_intr); | |
+ print_stat(seq, hsotg, wakeup_intr); | |
+ print_stat(seq, hsotg, suspend_intr); | |
+ print_stat(seq, hsotg, lpm_intr); | |
+ print_stat(seq, hsotg, device_port_intr); | |
+ print_stat(seq, hsotg, host_port_intr); | |
+ print_stat(seq, hsotg, unhandled_intr); | |
+ | |
+ print_stat(seq, hsotg, hcd_intr); | |
+ print_stat(seq, hsotg, hcd_unhandled_intr1); | |
+ print_stat(seq, hsotg, hcd_unhandled_intr2); | |
+ print_stat(seq, hsotg, hcd_sof_intr); | |
+ print_stat(seq, hsotg, hcd_rx_fifo_intr); | |
+ print_stat(seq, hsotg, hcd_tx_fifo_intr); | |
+ print_stat(seq, hsotg, hcd_port_intr); | |
+ print_stat(seq, hsotg, hcd_hc_intr); | |
+ print_stat(seq, hsotg, hcd_device_intr); | |
+ | |
+ print_stat(seq, hsotg, lx_state); | |
+ print_stat(seq, hsotg, op_state); | |
+ print_stat(seq, hsotg, bus_suspended); | |
+ return 0; | |
+} | |
+DEFINE_SHOW_ATTRIBUTE(stats); | |
+ | |
int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) | |
{ | |
int ret; | |
@@ -783,6 +821,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) | |
debugfs_create_file("params", 0444, root, hsotg, ¶ms_fops); | |
debugfs_create_file("hw_params", 0444, root, hsotg, &hw_params_fops); | |
debugfs_create_file("dr_mode", 0444, root, hsotg, &dr_mode_fops); | |
+ debugfs_create_file("stats", 0444, root, hsotg, &stats_fops); | |
/* Add gadget debugfs nodes */ | |
dwc2_hsotg_create_debug(hsotg); | |
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c | |
index 5c7538d498dd..6ec4905d3ef8 100644 | |
--- a/drivers/usb/dwc2/hcd_intr.c | |
+++ b/drivers/usb/dwc2/hcd_intr.c | |
@@ -2212,11 +2212,13 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg) | |
} | |
spin_lock(&hsotg->lock); | |
+ hsotg->hcd_intr++; | |
/* Check if HOST Mode */ | |
if (dwc2_is_host_mode(hsotg)) { | |
gintsts = dwc2_read_core_intr(hsotg); | |
if (!gintsts) { | |
+ hsotg->hcd_unhandled_intr1++; | |
spin_unlock(&hsotg->lock); | |
return retval; | |
} | |
@@ -2237,18 +2239,30 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg) | |
"DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", | |
gintsts); | |
- if (gintsts & GINTSTS_SOF) | |
+ if (gintsts & GINTSTS_SOF) { | |
dwc2_sof_intr(hsotg); | |
- if (gintsts & GINTSTS_RXFLVL) | |
+ hsotg->hcd_sof_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_RXFLVL) { | |
dwc2_rx_fifo_level_intr(hsotg); | |
- if (gintsts & GINTSTS_NPTXFEMP) | |
+ hsotg->hcd_rx_fifo_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_NPTXFEMP) { | |
dwc2_np_tx_fifo_empty_intr(hsotg); | |
- if (gintsts & GINTSTS_PRTINT) | |
+ hsotg->hcd_tx_fifo_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_PRTINT) { | |
dwc2_port_intr(hsotg); | |
- if (gintsts & GINTSTS_HCHINT) | |
+ hsotg->hcd_port_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_HCHINT) { | |
dwc2_hc_intr(hsotg); | |
- if (gintsts & GINTSTS_PTXFEMP) | |
+ hsotg->hcd_hc_intr++; | |
+ } | |
+ if (gintsts & GINTSTS_PTXFEMP) { | |
dwc2_perio_tx_fifo_empty_intr(hsotg); | |
+ hsotg->hcd_tx_fifo_intr++; | |
+ } | |
if (dbg_gintsts) { | |
dev_vdbg(hsotg->dev, | |
@@ -2258,6 +2272,11 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg) | |
dwc2_readl(hsotg, GINTSTS), | |
dwc2_readl(hsotg, GINTMSK)); | |
} | |
+ | |
+ if (retval == IRQ_NONE) | |
+ hsotg->hcd_unhandled_intr2++; | |
+ } else { | |
+ hsotg->hcd_device_intr++; | |
} | |
spin_unlock(&hsotg->lock); | |
-- | |
2.34.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment