summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2026-06-03 12:11:27 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-06-03 19:23:29 +0200
commit724eab31dd7edea68b731b7635f91e3158c61d2a (patch)
tree2587607776f3ca885f0afd9cd5c8e0dfdc17fde3 /drivers
parentde58a7d374eb0caae801704c3e47400b41a53acf (diff)
xhci: dbc: add timestamps to DbC state changes in a new helper.
The timestamp helps us track when a state changed the last time. It allows us to detect if DbC is stuck in connected state for too long, and can later be used to enable runtime suspend if there is no activity for some time Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://patch.msgid.link/20260603091132.1110849-11-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/xhci-dbgcap.c18
-rw-r--r--drivers/usb/host/xhci-dbgcap.h1
2 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 8cf0f0356bf1..34441ffa5e15 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -644,6 +644,12 @@ static int xhci_dbc_enable_dce(struct xhci_dbc *dbc, bool enable)
done_state, 1000);
}
+static void xhci_dbc_set_state(struct xhci_dbc *dbc, enum dbc_state new_state)
+{
+ dbc->state_timestamp = jiffies;
+ dbc->state = new_state;
+}
+
static int xhci_do_dbc_start(struct xhci_dbc *dbc)
{
int ret;
@@ -663,7 +669,7 @@ static int xhci_do_dbc_start(struct xhci_dbc *dbc)
if (ret)
return ret;
- dbc->state = DS_ENABLED;
+ xhci_dbc_set_state(dbc, DS_ENABLED);
return 0;
}
@@ -725,7 +731,7 @@ static void xhci_dbc_stop(struct xhci_dbc *dbc)
spin_lock_irqsave(&dbc->lock, flags);
writel(0, &dbc->regs->control);
- dbc->state = DS_DISABLED;
+ xhci_dbc_set_state(dbc, DS_DISABLED);
spin_unlock_irqrestore(&dbc->lock, flags);
xhci_dbc_mem_cleanup(dbc);
@@ -896,7 +902,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
case DS_ENABLED:
portsc = readl(&dbc->regs->portsc);
if (portsc & DBC_PORTSC_CONN_STATUS) {
- dbc->state = DS_CONNECTED;
+ xhci_dbc_set_state(dbc, DS_CONNECTED);
dev_info(dbc->dev, "DbC connected\n");
}
@@ -904,7 +910,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
case DS_CONNECTED:
ctrl = readl(&dbc->regs->control);
if (ctrl & DBC_CTRL_DBC_RUN) {
- dbc->state = DS_CONFIGURED;
+ xhci_dbc_set_state(dbc, DS_CONFIGURED);
dev_info(dbc->dev, "DbC configured\n");
portsc = readl(&dbc->regs->portsc);
writel(portsc, &dbc->regs->portsc);
@@ -919,7 +925,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
if (!(portsc & DBC_PORTSC_PORT_ENABLED) &&
!(portsc & DBC_PORTSC_CONN_STATUS)) {
dev_info(dbc->dev, "DbC cable unplugged\n");
- dbc->state = DS_ENABLED;
+ xhci_dbc_set_state(dbc, DS_ENABLED);
xhci_dbc_flush_requests(dbc);
xhci_dbc_reinit_ep_rings(dbc);
return EVT_DISC;
@@ -929,7 +935,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
if (portsc & DBC_PORTSC_RESET_CHANGE) {
dev_info(dbc->dev, "DbC port reset\n");
writel(portsc, &dbc->regs->portsc);
- dbc->state = DS_ENABLED;
+ xhci_dbc_set_state(dbc, DS_ENABLED);
xhci_dbc_flush_requests(dbc);
xhci_dbc_reinit_ep_rings(dbc);
return EVT_DISC;
diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h
index f4c0169a1b4d..b3efea43a6be 100644
--- a/drivers/usb/host/xhci-dbgcap.h
+++ b/drivers/usb/host/xhci-dbgcap.h
@@ -163,6 +163,7 @@ struct xhci_dbc {
struct delayed_work event_work;
unsigned int poll_interval; /* ms */
unsigned long xfer_timestamp;
+ unsigned long state_timestamp;
unsigned resume_required:1;
struct dbc_ep eps[2];