* [PATCH 0/7] usb: xhci: Port Register Set improvements
@ 2025-09-04 15:42 Niklas Neronin
2025-09-04 15:42 ` [PATCH 1/7] usb: xhci: correct indentation for PORTCS tracing function Niklas Neronin
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
The aim of this patch set is to introduce tracing for PORTCS writes and
implement a Port Register Set struct.
Introduces a new struct for the Host Controller USB Port Register Set.
The current implementation accesses these registers through a single
'__le32' pointer, which, in conjunction with a macro, navigates to the
specific register using (base address + offset).
Currently, how its accessed | Register Name
--------------------------------------------------------------------------
port->addr | Port Status and Control
port->addr + PORTPMSC | Port Power Management Status and Control
port->addr + PORTLI | Port Link Info
port->addr + PORTHLPMC | Port Hardware LPM Control
After, how its accessed | Register Name
--------------------------------------------------------------------------
port->port_reg->portsc | Port Status and Control
port->port_reg->portpmsc | Port Power Management Status and Control
port->port_reg->portli | Port Link Info
port->port_reg->porthlmpc | Port Hardware LPM Control
These changes make it easier for future modification and their review.
Note:
I have chosen to split the struct changes across three separate commits
due to the substantial number of modified lines. Personally, I find that
minor typos are more likely to occur when dealing with larger patches.
However, I am open to consolidating these patches into a single commit
after review.
Niklas Neronin (7):
usb: xhci: correct indentation for PORTCS tracing function
usb: xhci: align PORTCS trace with one-based port numbering
usb: xhci: improve xhci_decode_portsc()
usb: xhci: add tracing for PORTCS register writes
usb: xhci: add USB Port Register Set struct
usb: xhci: implement USB Port Register Set struct
usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
drivers/usb/host/xhci-debugfs.c | 6 +-
drivers/usb/host/xhci-hub.c | 115 ++++++++++++++++----------------
drivers/usb/host/xhci-mem.c | 3 +-
drivers/usb/host/xhci-pci.c | 4 +-
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci-tegra.c | 12 ++--
drivers/usb/host/xhci-trace.h | 39 ++++++-----
drivers/usb/host/xhci.c | 41 +++++++-----
drivers/usb/host/xhci.h | 94 +++++++++++++-------------
9 files changed, 161 insertions(+), 155 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/7] usb: xhci: correct indentation for PORTCS tracing function
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 2/7] usb: xhci: align PORTCS trace with one-based port numbering Niklas Neronin
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
Correct the indentation in USB Port Register Set (PORTCS) tracing.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-trace.h | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index bfb5c5c17012..f303ce600ff5 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -541,23 +541,23 @@ DEFINE_EVENT(xhci_log_ring, xhci_inc_deq,
);
DECLARE_EVENT_CLASS(xhci_log_portsc,
- TP_PROTO(struct xhci_port *port, u32 portsc),
- TP_ARGS(port, portsc),
- TP_STRUCT__entry(
- __field(u32, busnum)
- __field(u32, portnum)
- __field(u32, portsc)
- ),
- TP_fast_assign(
- __entry->busnum = port->rhub->hcd->self.busnum;
- __entry->portnum = port->hcd_portnum;
- __entry->portsc = portsc;
- ),
- TP_printk("port %d-%d: %s",
- __entry->busnum,
- __entry->portnum,
- xhci_decode_portsc(__get_buf(XHCI_MSG_MAX), __entry->portsc)
- )
+ TP_PROTO(struct xhci_port *port, u32 portsc),
+ TP_ARGS(port, portsc),
+ TP_STRUCT__entry(
+ __field(u32, busnum)
+ __field(u32, portnum)
+ __field(u32, portsc)
+ ),
+ TP_fast_assign(
+ __entry->busnum = port->rhub->hcd->self.busnum;
+ __entry->portnum = port->hcd_portnum;
+ __entry->portsc = portsc;
+ ),
+ TP_printk("port %d-%d: %s",
+ __entry->busnum,
+ __entry->portnum,
+ xhci_decode_portsc(__get_buf(XHCI_MSG_MAX), __entry->portsc)
+ )
);
DEFINE_EVENT(xhci_log_portsc, xhci_handle_port_status,
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/7] usb: xhci: align PORTCS trace with one-based port numbering
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
2025-09-04 15:42 ` [PATCH 1/7] usb: xhci: correct indentation for PORTCS tracing function Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 3/7] usb: xhci: improve xhci_decode_portsc() Niklas Neronin
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
In the xHCI driver, port numbers are typically described using a one-based
index. However, tracing currently uses a zero-based index. To ensure
consistency between tracing and dynamic debugging, update the trace port
number to use a one-based index.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-trace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index f303ce600ff5..9abc904f1749 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -550,7 +550,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc,
),
TP_fast_assign(
__entry->busnum = port->rhub->hcd->self.busnum;
- __entry->portnum = port->hcd_portnum;
+ __entry->portnum = port->hcd_portnum + 1;
__entry->portsc = portsc;
),
TP_printk("port %d-%d: %s",
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/7] usb: xhci: improve xhci_decode_portsc()
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
2025-09-04 15:42 ` [PATCH 1/7] usb: xhci: correct indentation for PORTCS tracing function Niklas Neronin
2025-09-04 15:42 ` [PATCH 2/7] usb: xhci: align PORTCS trace with one-based port numbering Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 4/7] usb: xhci: add tracing for PORTCS register writes Niklas Neronin
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
This patch improves xhci_decode_portsc(), which is used in PORTCS tracing.
The upcoming patch will add tracing to all PORTCS writes.
Read-Write 1 to Clear (RW1C) bits are now grouped together and prefixed
with "RW1C: " if needed. This is because the meaning of a set RW1C bit
differs between reading and writing. For instance, when reading 'PORT_PE',
a value of '1' indicates the port is enabled, while '0' means it is
disabled. Conversely, writing a '1' to 'PORT_PE' signifies that the port
is being disabled.
Add Port Link State Write Strobe (LWS) to the decoder.
Simplify and reduce the length of the message.
==== Examples ====
Before:
0x00201203 Powered Connected Enabled Link:U0 PortSpeed:4 Change: PRC Wake:
0x0a0002a0 Powered Not-connected Disabled Link:RxDetect PortSpeed:0 \
Change: Wake: WCE WOE
After:
0x00201203 Power:1 Connect:1 Link:U0 Speed:4 RW1C: PED PRC
0x0a0002a0 Power:1 Connect:0 Link:RxDetect Speed:0 WCE WOE
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
I am aware that the 'XHCI_PORT_RW1CS' macro could replace
'(PORT_PE | PORT_CHANGE_MASK)'. However, it is not located in xhci-port.h,
does not utilize established port macros, and is inaccessible in xhci.h.
To avoid complicating this patch set further, I've decided to defer this
change to part 2. Otherwise, this patch set will grow forever :D
Part 2 will tackle xhci-port.h and all associated macros.
drivers/usb/host/xhci.h | 52 +++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a20f4e7cd43a..f37965e64fd5 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2395,37 +2395,22 @@ static inline const char *xhci_decode_portsc(char *str, u32 portsc)
if (portsc == ~(u32)0)
return str;
- ret += sprintf(str + ret, "%s %s %s Link:%s PortSpeed:%d ",
- portsc & PORT_POWER ? "Powered" : "Powered-off",
- portsc & PORT_CONNECT ? "Connected" : "Not-connected",
- portsc & PORT_PE ? "Enabled" : "Disabled",
+ ret += sprintf(str + ret, "Power:%d Connect:%d Link:%s Speed:%d ",
+ !!(portsc & PORT_POWER),
+ !!(portsc & PORT_CONNECT),
xhci_portsc_link_state_string(portsc),
DEV_PORT_SPEED(portsc));
- if (portsc & PORT_OC)
- ret += sprintf(str + ret, "OverCurrent ");
+ /* Read-Write 1 to Set */
if (portsc & PORT_RESET)
ret += sprintf(str + ret, "In-Reset ");
- ret += sprintf(str + ret, "Change: ");
- if (portsc & PORT_CSC)
- ret += sprintf(str + ret, "CSC ");
- if (portsc & PORT_PEC)
- ret += sprintf(str + ret, "PEC ");
- if (portsc & PORT_WRC)
- ret += sprintf(str + ret, "WRC ");
- if (portsc & PORT_OCC)
- ret += sprintf(str + ret, "OCC ");
- if (portsc & PORT_RC)
- ret += sprintf(str + ret, "PRC ");
- if (portsc & PORT_PLC)
- ret += sprintf(str + ret, "PLC ");
- if (portsc & PORT_CEC)
- ret += sprintf(str + ret, "CEC ");
+ if (portsc & PORT_OC)
+ ret += sprintf(str + ret, "OCA ");
+ if (portsc & PORT_LINK_STROBE)
+ ret += sprintf(str + ret, "LWS ");
if (portsc & PORT_CAS)
ret += sprintf(str + ret, "CAS ");
-
- ret += sprintf(str + ret, "Wake: ");
if (portsc & PORT_WKCONN_E)
ret += sprintf(str + ret, "WCE ");
if (portsc & PORT_WKDISC_E)
@@ -2433,6 +2418,27 @@ static inline const char *xhci_decode_portsc(char *str, u32 portsc)
if (portsc & PORT_WKOC_E)
ret += sprintf(str + ret, "WOE ");
+ /* Read-Write 1 to Clear */
+ if (portsc & (PORT_PE | PORT_CHANGE_MASK)) {
+ ret += sprintf(str + ret, "RW1C: ");
+ if (portsc & PORT_PE)
+ ret += sprintf(str + ret, "PED ");
+ if (portsc & PORT_CSC)
+ ret += sprintf(str + ret, "CSC ");
+ if (portsc & PORT_PEC)
+ ret += sprintf(str + ret, "PEC ");
+ if (portsc & PORT_WRC)
+ ret += sprintf(str + ret, "WRC ");
+ if (portsc & PORT_OCC)
+ ret += sprintf(str + ret, "OCC ");
+ if (portsc & PORT_RC)
+ ret += sprintf(str + ret, "PRC ");
+ if (portsc & PORT_PLC)
+ ret += sprintf(str + ret, "PLC ");
+ if (portsc & PORT_CEC)
+ ret += sprintf(str + ret, "CEC ");
+ }
+
return str;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/7] usb: xhci: add tracing for PORTCS register writes
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
` (2 preceding siblings ...)
2025-09-04 15:42 ` [PATCH 3/7] usb: xhci: improve xhci_decode_portsc() Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 5/7] usb: xhci: add USB Port Register Set struct Niklas Neronin
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
Introduce a dedicated write function for the USB Port Register Set
(PORTCS) that includes tracing capabilities for values written to the
PORTCS register. This enhancement minimizes code duplication and improves
debugging.
The PORTCS register is part of the Host Controller USB Port Register Set,
comprising 4 x 32-bit registers. As the first register, PORTCS is accessed
directly via 'port->addr'. Future commits will introduce a dedicated
Port register struct to further streamline access.
By adding the xhci_set_portcs() function prior to these changes, we
significantly reduce the number of same line modifications required.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-debugfs.c | 2 +-
drivers/usb/host/xhci-hub.c | 33 ++++++++++++++++-----------------
drivers/usb/host/xhci-pci.c | 2 +-
drivers/usb/host/xhci-trace.h | 5 +++++
drivers/usb/host/xhci.c | 8 +++++++-
drivers/usb/host/xhci.h | 1 +
6 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index c6d44977193f..11edb5c54cfa 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -367,7 +367,7 @@ static ssize_t xhci_port_write(struct file *file, const char __user *ubuf,
portsc = xhci_port_state_to_neutral(portsc);
portsc &= ~PORT_PLS_MASK;
portsc |= PORT_LINK_STROBE | XDEV_COMP_MODE;
- writel(portsc, port->addr);
+ xhci_set_portsc(port, portsc);
spin_unlock_irqrestore(&xhci->lock, flags);
} else {
return -EINVAL;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 92bb84f8132a..155fb9159934 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -570,7 +570,7 @@ static void xhci_disable_port(struct xhci_hcd *xhci, struct xhci_port *port)
portsc = xhci_port_state_to_neutral(portsc);
/* Write 1 to disable the port */
- writel(portsc | PORT_PE, port->addr);
+ xhci_set_portsc(port, portsc | PORT_PE);
portsc = readl(port->addr);
xhci_dbg(xhci, "disable port %d-%d, portsc: 0x%x\n",
@@ -578,7 +578,7 @@ static void xhci_disable_port(struct xhci_hcd *xhci, struct xhci_port *port)
}
static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
- u16 wIndex, __le32 __iomem *addr, u32 port_status)
+ u16 wIndex, struct xhci_port *port, u32 port_status)
{
char *port_change_bit;
u32 status;
@@ -621,8 +621,8 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
return;
}
/* Change bits are all write 1 to clear */
- writel(port_status | status, addr);
- port_status = readl(addr);
+ xhci_set_portsc(port, port_status | status);
+ port_status = readl(port->addr);
xhci_dbg(xhci, "clear port%d %s change, portsc: 0x%x\n",
wIndex + 1, port_change_bit, port_status);
@@ -659,11 +659,11 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
if (on) {
/* Power on */
- writel(temp | PORT_POWER, port->addr);
+ xhci_set_portsc(port, temp | PORT_POWER);
readl(port->addr);
} else {
/* Power off */
- writel(temp & ~PORT_POWER, port->addr);
+ xhci_set_portsc(port, temp & ~PORT_POWER);
}
spin_unlock_irqrestore(&xhci->lock, *flags);
@@ -806,7 +806,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
temp = xhci_port_state_to_neutral(portsc);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
- writel(temp, port->addr);
+ xhci_set_portsc(port, temp);
xhci_dbg(xhci, "Set port %d-%d link state, portsc: 0x%x, write 0x%x",
port->rhub->hcd->self.busnum, port->hcd_portnum + 1,
@@ -836,7 +836,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
else
temp &= ~PORT_WKOC_E;
- writel(temp, port->addr);
+ xhci_set_portsc(port, temp);
}
/* Test and clear port RWC bit */
@@ -849,7 +849,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, struct xhci_port *port,
if (temp & port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
- writel(temp, port->addr);
+ xhci_set_portsc(port, temp);
}
}
@@ -1372,7 +1372,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp |= PORT_CSC | PORT_PEC | PORT_WRC |
PORT_OCC | PORT_RC | PORT_PLC |
PORT_CEC;
- writel(temp | PORT_PE, port->addr);
+ xhci_set_portsc(port, temp | PORT_PE);
temp = readl(port->addr);
break;
}
@@ -1501,7 +1501,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
- writel(temp, port->addr);
+ xhci_set_portsc(port, temp);
temp = readl(port->addr);
xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n",
@@ -1515,7 +1515,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
- writel(temp, port->addr);
+ xhci_set_portsc(port, temp);
temp = readl(port->addr);
break;
case USB_PORT_FEAT_U1_TIMEOUT:
@@ -1604,8 +1604,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_C_ENABLE:
case USB_PORT_FEAT_C_PORT_LINK_STATE:
case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
- xhci_clear_port_change_bit(xhci, wValue, wIndex,
- port->addr, temp);
+ xhci_clear_port_change_bit(xhci, wValue, wIndex, port, temp);
break;
case USB_PORT_FEAT_ENABLE:
xhci_disable_port(xhci, port);
@@ -1830,7 +1829,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
spin_lock_irqsave(&xhci->lock, flags);
}
}
- writel(portsc_buf[port_index], ports[port_index]->addr);
+ xhci_set_portsc(ports[port_index], portsc_buf[port_index]);
}
hcd->state = HC_STATE_SUSPENDED;
bus_state->next_statechange = jiffies + msecs_to_jiffies(10);
@@ -1864,7 +1863,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
/* clear wakeup/change bits, and do a warm port reset */
portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
portsc |= PORT_WR;
- writel(portsc, port->addr);
+ xhci_set_portsc(port, portsc);
/* flush write */
readl(port->addr);
return true;
@@ -1943,7 +1942,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
}
/* disable wake for all ports, write new link state if needed */
portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
- writel(portsc, ports[port_index]->addr);
+ xhci_set_portsc(ports[port_index], portsc);
}
/* USB2 specific resume signaling delay and U0 link state transition */
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 00fac8b233d2..4df8dfd13443 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -912,7 +912,7 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
xhci_dbg(xhci, "port %d-%d in U3 without wakeup, disable it\n",
port->rhub->hcd->self.busnum, port->hcd_portnum + 1);
portsc = xhci_port_state_to_neutral(portsc);
- writel(portsc | PORT_PE, port->addr);
+ xhci_set_portsc(port, portsc | PORT_PE);
}
return 0;
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 9abc904f1749..4d3abacf92c7 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -575,6 +575,11 @@ DEFINE_EVENT(xhci_log_portsc, xhci_hub_status_data,
TP_ARGS(port, portsc)
);
+DEFINE_EVENT(xhci_log_portsc, xhci_set_portsc,
+ TP_PROTO(struct xhci_port *port, u32 portsc),
+ TP_ARGS(port, portsc)
+);
+
DECLARE_EVENT_CLASS(xhci_log_doorbell,
TP_PROTO(u32 slot, u32 doorbell),
TP_ARGS(slot, doorbell),
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 47151ca527bf..0d380fb3fcd6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -41,6 +41,12 @@ static unsigned long long quirks;
module_param(quirks, ullong, S_IRUGO);
MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
+void xhci_set_portsc(struct xhci_port *port, u32 val)
+{
+ trace_xhci_set_portsc(port, val);
+ writel(val, port->addr);
+}
+
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
{
struct xhci_segment *seg;
@@ -907,7 +913,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
t2 |= PORT_CSC;
if (t1 != t2) {
- writel(t2, rhub->ports[i]->addr);
+ xhci_set_portsc(rhub->ports[i], t2);
xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
rhub->hcd->self.busnum, i + 1, portsc, t2);
}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f37965e64fd5..20bc5ae3500d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1957,6 +1957,7 @@ void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
struct xhci_interrupter *ir,
bool clear_ehb);
void xhci_add_interrupter(struct xhci_hcd *xhci, unsigned int intr_num);
+void xhci_set_portsc(struct xhci_port *port, u32 val);
/* xHCI roothub code */
void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/7] usb: xhci: add USB Port Register Set struct
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
` (3 preceding siblings ...)
2025-09-04 15:42 ` [PATCH 4/7] usb: xhci: add tracing for PORTCS register writes Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 6/7] usb: xhci: implement " Niklas Neronin
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
Introduce a new struct for the Host Controller USB Port Register Set to
enhance readability and maintainability.
The Host Controller Operational Registers (struct 'xhci_op_regs') span from
offset 0x0 to 0x3FF and consist of fixed fields. Following these fixed
fields are the Host Controller USB Port Register Sets, which are dynamic
and repeat from 1 to MaxPorts, as defined by HCSPARAMS1.
Currently, the struct 'xhci_op_regs' includes:
__le32 port_status_base; The first PORTSC
__le32 port_power_base; The first PORTPMSC
__le32 port_link_base; The first PORTLI
__le32 reserved5; The first PORTHLPMC, not reserved
__le32 reserved6[NUM_PORT_REGS*254]; Port registers 2 to MaxPorts
Replace this with the simpler:
struct xhci_port_regs port_regs[]; Port registers 1 to MaxPorts
Host Controller USB Port Register Set:
| Offset | Mnemonic | Register Name
--------------------------------------------------------------------------
| 0x0 | PORTSC | Port Status and Control
| 0x4 | PORTPMSC | Port Power Management Status and Control
| 0x8 | PORTLI | Port Link Info
| 0xC | PORTHLPMC | Port Hardware LPM Control
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 3 +--
drivers/usb/host/xhci.h | 36 ++++++++++++++++--------------------
2 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 07289333a1e8..edd37108e5a8 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2204,8 +2204,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
return -ENOMEM;
for (i = 0; i < num_ports; i++) {
- xhci->hw_ports[i].addr = &xhci->op_regs->port_status_base +
- NUM_PORT_REGS * i;
+ xhci->hw_ports[i].addr = &xhci->op_regs->port_regs[i].portsc;
xhci->hw_ports[i].hw_portnum = i;
init_completion(&xhci->hw_ports[i].rexit_done);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 20bc5ae3500d..5b04757325c1 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -66,14 +66,25 @@ struct xhci_cap_regs {
/* Reserved up to (CAPLENGTH - 0x1C) */
};
-/* Number of registers per port */
-#define NUM_PORT_REGS 4
-
#define PORTSC 0
#define PORTPMSC 1
#define PORTLI 2
#define PORTHLPMC 3
+/*
+ * struct xhci_port_regs - Host Controller USB Port Register Set. xHCI spec 5.4.8
+ * @portsc: Port Status and Control
+ * @portpmsc: Port Power Management Status and Control
+ * @portli: Port Link Info
+ * @porthlmpc: Port Hardware LPM Control
+ */
+struct xhci_port_regs {
+ __le32 portsc;
+ __le32 portpmsc;
+ __le32 portli;
+ __le32 porthlmpc;
+};
+
/**
* struct xhci_op_regs - xHCI Host Controller Operational Registers.
* @command: USBCMD - xHC command register
@@ -85,16 +96,7 @@ struct xhci_cap_regs {
* @cmd_ring: CRP - 64-bit Command Ring Pointer
* @dcbaa_ptr: DCBAAP - 64-bit Device Context Base Address Array Pointer
* @config_reg: CONFIG - Configure Register
- * @port_status_base: PORTSCn - base address for Port Status and Control
- * Each port has a Port Status and Control register,
- * followed by a Port Power Management Status and Control
- * register, a Port Link Info register, and a reserved
- * register.
- * @port_power_base: PORTPMSCn - base address for
- * Port Power Management Status and Control
- * @port_link_base: PORTLIn - base address for Port Link Info (current
- * Link PM state and control) for USB 2.1 and USB 3.0
- * devices.
+ * @port_regs: Port Register Sets, from 1 to MaxPorts (defined by HCSPARAMS1).
*/
struct xhci_op_regs {
__le32 command;
@@ -110,13 +112,7 @@ struct xhci_op_regs {
__le32 config_reg;
/* rsvd: offset 0x3C-3FF */
__le32 reserved4[241];
- /* port 1 registers, which serve as a base address for other ports */
- __le32 port_status_base;
- __le32 port_power_base;
- __le32 port_link_base;
- __le32 reserved5;
- /* registers for ports 2-255 */
- __le32 reserved6[NUM_PORT_REGS*254];
+ struct xhci_port_regs port_regs[];
};
/* USBCMD - USB command - command bitmasks */
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/7] usb: xhci: implement USB Port Register Set struct
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
` (4 preceding siblings ...)
2025-09-04 15:42 ` [PATCH 5/7] usb: xhci: add USB Port Register Set struct Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-04 15:42 ` [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port' Niklas Neronin
2025-09-05 1:57 ` [PATCH 0/7] usb: xhci: Port Register Set improvements Peter Chen (CIX)
7 siblings, 0 replies; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
Refactor the 'xhci_port' struct by changing the 'addr' field from a
'__le32' pointer to a pointer to the 'xhci_port_regs' struct.
Previously, the 'xhci_port' struct contained a '__le32' pointer named addr,
which pointed to the Host Controller USB Port Register Set.
Accessing specific registers required using a macro,
such as port->addr + PORTHLPMC, which was less readable.
Before:
port->addr
port->addr + PORTPMSC
port->addr + PORTLI
port->addr + PORTHLPMC
After:
port->addr->portsc
port->addr->portpmsc
port->addr->portli
port->addr->porthlmpc
This change simplifies the code by directly accessing the registers through
the 'xhci_port_regs' struct, making it more intuitive and easier to
follow.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-debugfs.c | 4 +-
drivers/usb/host/xhci-hub.c | 84 ++++++++++++++++-----------------
drivers/usb/host/xhci-mem.c | 2 +-
drivers/usb/host/xhci-pci.c | 2 +-
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci-tegra.c | 12 ++---
drivers/usb/host/xhci.c | 35 +++++++-------
drivers/usb/host/xhci.h | 7 +--
8 files changed, 71 insertions(+), 77 deletions(-)
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 11edb5c54cfa..134b53ae01ce 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -329,7 +329,7 @@ static int xhci_portsc_show(struct seq_file *s, void *unused)
u32 portsc;
char str[XHCI_MSG_MAX];
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
seq_printf(s, "%s\n", xhci_decode_portsc(str, portsc));
return 0;
@@ -359,7 +359,7 @@ static ssize_t xhci_port_write(struct file *file, const char __user *ubuf,
return count;
spin_lock_irqsave(&xhci->lock, flags);
/* compliance mode can only be enabled on ports in RxDetect */
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
spin_unlock_irqrestore(&xhci->lock, flags);
return -EPERM;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 155fb9159934..15e790e992b3 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -299,7 +299,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
*/
memset(port_removable, 0, sizeof(port_removable));
for (i = 0; i < ports; i++) {
- portsc = readl(rhub->ports[i]->addr);
+ portsc = readl(&rhub->ports[i]->addr->portsc);
/* If a device is removable, PORTSC reports a 0, same as in the
* hub descriptor DeviceRemovable bits.
*/
@@ -356,7 +356,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
port_removable = 0;
/* bit 0 is reserved, bit 1 is for port 1, etc. */
for (i = 0; i < ports; i++) {
- portsc = readl(rhub->ports[i]->addr);
+ portsc = readl(&rhub->ports[i]->addr->portsc);
if (portsc & PORT_DEV_REMOVE)
port_removable |= 1 << (i + 1);
}
@@ -566,13 +566,13 @@ static void xhci_disable_port(struct xhci_hcd *xhci, struct xhci_port *port)
return;
}
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
portsc = xhci_port_state_to_neutral(portsc);
/* Write 1 to disable the port */
xhci_set_portsc(port, portsc | PORT_PE);
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
xhci_dbg(xhci, "disable port %d-%d, portsc: 0x%x\n",
hcd->self.busnum, port->hcd_portnum + 1, portsc);
}
@@ -622,7 +622,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
}
/* Change bits are all write 1 to clear */
xhci_set_portsc(port, port_status | status);
- port_status = readl(port->addr);
+ port_status = readl(&port->addr->portsc);
xhci_dbg(xhci, "clear port%d %s change, portsc: 0x%x\n",
wIndex + 1, port_change_bit, port_status);
@@ -650,7 +650,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
u32 temp;
hcd = port->rhub->hcd;
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
xhci_dbg(xhci, "set port power %d-%d %s, portsc: 0x%x\n",
hcd->self.busnum, port->hcd_portnum + 1, on ? "ON" : "OFF", temp);
@@ -660,7 +660,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
if (on) {
/* Power on */
xhci_set_portsc(port, temp | PORT_POWER);
- readl(port->addr);
+ readl(&port->addr->portsc);
} else {
/* Power off */
xhci_set_portsc(port, temp & ~PORT_POWER);
@@ -683,9 +683,9 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
/* xhci only supports test mode for usb2 ports */
port = xhci->usb2_rhub.ports[wIndex];
- temp = readl(port->addr + PORTPMSC);
+ temp = readl(&port->addr->portpmsc);
temp |= test_mode << PORT_TEST_MODE_SHIFT;
- writel(temp, port->addr + PORTPMSC);
+ writel(temp, &port->addr->portpmsc);
xhci->test_mode = test_mode;
if (test_mode == USB_TEST_FORCE_ENABLE)
xhci_start(xhci);
@@ -802,7 +802,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
u32 temp;
u32 portsc;
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
temp = xhci_port_state_to_neutral(portsc);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
@@ -818,7 +818,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
{
u32 temp;
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
temp = xhci_port_state_to_neutral(temp);
if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
@@ -845,7 +845,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, struct xhci_port *port,
{
u32 temp;
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if (temp & port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
@@ -1003,7 +1003,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
}
xhci_ring_device(xhci, port->slot_id);
} else {
- int port_status = readl(port->addr);
+ int port_status = readl(&port->addr->portsc);
xhci_warn(xhci, "Port resume timed out, port %d-%d: 0x%x\n",
hcd->self.busnum, wIndex + 1, port_status);
@@ -1264,7 +1264,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
wIndex--;
port = ports[portnum1 - 1];
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1289,7 +1289,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
retval = -EINVAL;
break;
}
- port_li = readl(port->addr + PORTLI);
+ port_li = readl(&port->addr->portli);
status = xhci_get_ext_port_status(temp, port_li);
put_unaligned_le32(status, &buf[4]);
}
@@ -1310,7 +1310,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
port = ports[portnum1 - 1];
wIndex--;
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1320,7 +1320,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* FIXME: What new port features do we need to support? */
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if ((temp & PORT_PLS_MASK) != XDEV_U0) {
/* Resume the port to U0 first */
xhci_set_link_state(xhci, port, XDEV_U0);
@@ -1332,7 +1332,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
* a port unless the port reports that it is in the
* enabled (PED = ‘1’,PLS < ‘3’) state.
*/
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if ((temp & PORT_PE) == 0 || (temp & PORT_RESET)
|| (temp & PORT_PLS_MASK) >= XDEV_U3) {
xhci_warn(xhci, "USB core suspending port %d-%d not in U0/U1/U2\n",
@@ -1355,11 +1355,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
msleep(10); /* wait device to enter */
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
bus_state->suspended_ports |= 1 << wIndex;
break;
case USB_PORT_FEAT_LINK_STATE:
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
/* Disable port */
if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
xhci_dbg(xhci, "Disable port %d-%d\n",
@@ -1373,7 +1373,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
PORT_OCC | PORT_RC | PORT_PLC |
PORT_CEC;
xhci_set_portsc(port, temp | PORT_PE);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
}
@@ -1382,7 +1382,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_dbg(xhci, "Enable port %d-%d\n",
hcd->self.busnum, portnum1);
xhci_set_link_state(xhci, port, link_state);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
}
@@ -1415,7 +1415,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
hcd->self.busnum, portnum1);
xhci_set_link_state(xhci, port, link_state);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
}
/* Port must be enabled */
@@ -1463,7 +1463,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n",
hcd->self.busnum, portnum1);
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
}
@@ -1481,12 +1481,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
spin_unlock_irqrestore(&xhci->lock, flags);
while (retries--) {
usleep_range(4000, 8000);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if ((temp & PORT_PLS_MASK) == XDEV_U3)
break;
}
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
bus_state->suspended_ports |= 1 << wIndex;
}
break;
@@ -1503,36 +1503,36 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = (temp | PORT_RESET);
xhci_set_portsc(port, temp);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n",
hcd->self.busnum, portnum1, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
xhci_set_remote_wake_mask(xhci, port, wake_mask);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
xhci_dbg(xhci, "set port remote wake mask, actual port %d-%d status = 0x%x\n",
hcd->self.busnum, portnum1, temp);
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
xhci_set_portsc(port, temp);
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
case USB_PORT_FEAT_U1_TIMEOUT:
if (hcd->speed < HCD_USB3)
goto error;
- temp = readl(port->addr + PORTPMSC);
+ temp = readl(&port->addr->portpmsc);
temp &= ~PORT_U1_TIMEOUT_MASK;
temp |= PORT_U1_TIMEOUT(timeout);
- writel(temp, port->addr + PORTPMSC);
+ writel(temp, &port->addr->portpmsc);
break;
case USB_PORT_FEAT_U2_TIMEOUT:
if (hcd->speed < HCD_USB3)
goto error;
- temp = readl(port->addr + PORTPMSC);
+ temp = readl(&port->addr->portpmsc);
temp &= ~PORT_U2_TIMEOUT_MASK;
temp |= PORT_U2_TIMEOUT(timeout);
- writel(temp, port->addr + PORTPMSC);
+ writel(temp, &port->addr->portpmsc);
break;
case USB_PORT_FEAT_TEST:
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
@@ -1548,7 +1548,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
goto error;
}
/* unblock any posted writes */
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
break;
case ClearPortFeature:
if (!portnum1 || portnum1 > max_ports)
@@ -1557,7 +1557,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
port = ports[portnum1 - 1];
wIndex--;
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1567,7 +1567,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_port_state_to_neutral(temp);
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
- temp = readl(port->addr);
+ temp = readl(&port->addr->portsc);
xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n");
xhci_dbg(xhci, "PORTSC %04x\n", temp);
if (temp & PORT_RESET)
@@ -1682,7 +1682,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
/* For each port, did anything change? If so, set that bit in buf. */
for (i = 0; i < max_ports; i++) {
- temp = readl(ports[i]->addr);
+ temp = readl(&ports[i]->addr->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1751,7 +1751,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
u32 t1, t2;
int retries = 10;
retry:
- t1 = readl(ports[port_index]->addr);
+ t1 = readl(&ports[port_index]->addr->portsc);
t2 = xhci_port_state_to_neutral(t1);
portsc_buf[port_index] = 0;
@@ -1850,7 +1850,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
{
u32 portsc;
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
/* if any of these are set we are not stuck */
if (portsc & (PORT_CONNECT | PORT_CAS))
@@ -1865,7 +1865,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
portsc |= PORT_WR;
xhci_set_portsc(port, portsc);
/* flush write */
- readl(port->addr);
+ readl(&port->addr->portsc);
return true;
}
@@ -1912,7 +1912,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
}
port_index = max_ports;
while (port_index--) {
- portsc = readl(ports[port_index]->addr);
+ portsc = readl(&ports[port_index]->addr->portsc);
/* warm reset CAS limited ports stuck in polling/compliance */
if ((xhci->quirks & XHCI_MISSING_CAS) &&
@@ -1963,7 +1963,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* poll for U0 link state complete, both USB2 and USB3 */
for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) {
- sret = xhci_handshake(ports[port_index]->addr, PORT_PLC,
+ sret = xhci_handshake(&ports[port_index]->addr->portsc, PORT_PLC,
PORT_PLC, 10 * 1000);
if (sret) {
xhci_warn(xhci, "port %d-%d resume PLC timeout\n",
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index edd37108e5a8..bfd8e471d3c2 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2204,7 +2204,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
return -ENOMEM;
for (i = 0; i < num_ports; i++) {
- xhci->hw_ports[i].addr = &xhci->op_regs->port_regs[i].portsc;
+ xhci->hw_ports[i].addr = &xhci->op_regs->port_regs[i];
xhci->hw_ports[i].hw_portnum = i;
init_completion(&xhci->hw_ports[i].rexit_done);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 4df8dfd13443..74d6a4f31956 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -891,7 +891,7 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
port = &xhci->hw_ports[i];
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
if ((portsc & PORT_PLS_MASK) != XDEV_U3)
continue;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ecd757d482c5..6241a8d28ab3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2023,7 +2023,7 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
hcd = port->rhub->hcd;
bus_state = &port->rhub->bus_state;
hcd_portnum = port->hcd_portnum;
- portsc = readl(port->addr);
+ portsc = readl(&port->addr->portsc);
xhci_dbg(xhci, "Port change event, %d-%d, id %d, portsc: 0x%x\n",
hcd->self.busnum, hcd_portnum + 1, port_id, portsc);
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 0c7af44d4dae..0ee5192f67fa 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -1969,7 +1969,7 @@ static bool xhci_hub_ports_suspended(struct xhci_hub *hub)
u32 value;
for (i = 0; i < hub->num_ports; i++) {
- value = readl(hub->ports[i]->addr);
+ value = readl(&hub->ports[i]->addr->portsc);
if ((value & PORT_PE) == 0)
continue;
@@ -2095,7 +2095,7 @@ static void tegra_xhci_enable_phy_sleepwalk_wake(struct tegra_xusb *tegra)
if (!is_host_mode_phy(tegra, i, j))
continue;
- portsc = readl(rhub->ports[index]->addr);
+ portsc = readl(&rhub->ports[index]->addr->portsc);
speed = tegra_xhci_portsc_to_speed(tegra, portsc);
tegra_xusb_padctl_enable_phy_sleepwalk(padctl, phy, speed);
tegra_xusb_padctl_enable_phy_wake(padctl, phy);
@@ -2190,7 +2190,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
for (i = 0; i < xhci->usb2_rhub.num_ports; i++) {
if (!xhci->usb2_rhub.ports[i])
continue;
- portsc = readl(xhci->usb2_rhub.ports[i]->addr);
+ portsc = readl(&xhci->usb2_rhub.ports[i]->addr->portsc);
tegra->lp0_utmi_pad_mask &= ~BIT(i);
if (((portsc & PORT_PLS_MASK) == XDEV_U3) || ((portsc & DEV_SPEED_MASK) == XDEV_FS))
tegra->lp0_utmi_pad_mask |= BIT(i);
@@ -2712,7 +2712,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
while (i--) {
if (!test_bit(i, &bus_state->resuming_ports))
continue;
- portsc = readl(ports[i]->addr);
+ portsc = readl(&ports[i]->addr->portsc);
if ((portsc & PORT_PLS_MASK) == XDEV_RESUME)
tegra_phy_xusb_utmi_pad_power_on(
tegra_xusb_get_phy(tegra, "usb2", (int) i));
@@ -2730,7 +2730,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
if (!index || index > rhub->num_ports)
return -EPIPE;
ports = rhub->ports;
- portsc = readl(ports[port]->addr);
+ portsc = readl(&ports[port]->addr->portsc);
if (portsc & PORT_CONNECT)
tegra_phy_xusb_utmi_pad_power_on(phy);
}
@@ -2749,7 +2749,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
if ((type_req == ClearPortFeature) && (value == USB_PORT_FEAT_C_CONNECTION)) {
ports = rhub->ports;
- portsc = readl(ports[port]->addr);
+ portsc = readl(&ports[port]->addr->portsc);
if (!(portsc & PORT_CONNECT)) {
/* We don't suspend the PAD while HNP role swap happens on the OTG
* port
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0d380fb3fcd6..676441dc3141 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -44,7 +44,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
void xhci_set_portsc(struct xhci_port *port, u32 val)
{
trace_xhci_set_portsc(port, val);
- writel(val, port->addr);
+ writel(val, &port->addr->portsc);
}
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
@@ -377,7 +377,7 @@ static void compliance_mode_recovery(struct timer_list *t)
return;
for (i = 0; i < rhub->num_ports; i++) {
- temp = readl(rhub->ports[i]->addr);
+ temp = readl(&rhub->ports[i]->addr->portsc);
if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
/*
* Compliance Mode Detected. Letting USB Core
@@ -900,7 +900,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
spin_lock_irqsave(&xhci->lock, flags);
for (i = 0; i < rhub->num_ports; i++) {
- portsc = readl(rhub->ports[i]->addr);
+ portsc = readl(&rhub->ports[i]->addr->portsc);
t1 = xhci_port_state_to_neutral(portsc);
t2 = t1;
@@ -940,7 +940,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb2_rhub.num_ports;
ports = xhci->usb2_rhub.ports;
while (port_index--) {
- portsc = readl(ports[port_index]->addr);
+ portsc = readl(&ports[port_index]->addr->portsc);
if (portsc & PORT_CHANGE_MASK ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -948,7 +948,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb3_rhub.num_ports;
ports = xhci->usb3_rhub.ports;
while (port_index--) {
- portsc = readl(ports[port_index]->addr);
+ portsc = readl(&ports[port_index]->addr->portsc);
if (portsc & (PORT_CHANGE_MASK | PORT_CAS) ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -4619,7 +4619,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_port **ports;
- __le32 __iomem *pm_addr, *hlpm_addr;
+ struct xhci_port_regs __iomem *port_regs;
u32 pm_val, hlpm_val, field;
unsigned int port_num;
unsigned long flags;
@@ -4644,9 +4644,8 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
ports = xhci->usb2_rhub.ports;
port_num = udev->portnum - 1;
- pm_addr = ports[port_num]->addr + PORTPMSC;
- pm_val = readl(pm_addr);
- hlpm_addr = ports[port_num]->addr + PORTHLPMC;
+ port_regs = ports[port_num]->addr;
+ pm_val = readl(&port_regs->portpmsc);
xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
str_enable_disable(enable), port_num + 1);
@@ -4675,30 +4674,30 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev);
- writel(hlpm_val, hlpm_addr);
+ writel(hlpm_val, &port_regs->porthlmpc);
/* flush write */
- readl(hlpm_addr);
+ readl(&port_regs->porthlmpc);
} else {
hird = xhci_calculate_hird_besl(xhci, udev);
}
pm_val &= ~PORT_HIRD_MASK;
pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
- writel(pm_val, pm_addr);
- pm_val = readl(pm_addr);
+ writel(pm_val, &port_regs->portpmsc);
+ pm_val = readl(&port_regs->portpmsc);
pm_val |= PORT_HLE;
- writel(pm_val, pm_addr);
+ writel(pm_val, &port_regs->portpmsc);
/* flush write */
- readl(pm_addr);
+ readl(&port_regs->portpmsc);
} else {
pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
- writel(pm_val, pm_addr);
+ writel(pm_val, &port_regs->portpmsc);
/* flush write */
- readl(pm_addr);
+ readl(&port_regs->portpmsc);
if (udev->usb2_hw_lpm_besl_capable) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_change_max_exit_latency(xhci, udev, 0);
- readl_poll_timeout(ports[port_num]->addr, pm_val,
+ readl_poll_timeout(&ports[port_num]->addr->portsc, pm_val,
(pm_val & PORT_PLS_MASK) == XDEV_U0,
100, 10000);
return 0;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 5b04757325c1..38edc430ee49 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -66,11 +66,6 @@ struct xhci_cap_regs {
/* Reserved up to (CAPLENGTH - 0x1C) */
};
-#define PORTSC 0
-#define PORTPMSC 1
-#define PORTLI 2
-#define PORTHLPMC 3
-
/*
* struct xhci_port_regs - Host Controller USB Port Register Set. xHCI spec 5.4.8
* @portsc: Port Status and Control
@@ -1469,7 +1464,7 @@ struct xhci_port_cap {
};
struct xhci_port {
- __le32 __iomem *addr;
+ struct xhci_port_regs __iomem *addr;
int hw_portnum;
int hcd_portnum;
struct xhci_hub *rhub;
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
` (5 preceding siblings ...)
2025-09-04 15:42 ` [PATCH 6/7] usb: xhci: implement " Niklas Neronin
@ 2025-09-04 15:42 ` Niklas Neronin
2025-09-05 2:40 ` Peter Chen (CIX)
2025-09-05 1:57 ` [PATCH 0/7] usb: xhci: Port Register Set improvements Peter Chen (CIX)
7 siblings, 1 reply; 13+ messages in thread
From: Niklas Neronin @ 2025-09-04 15:42 UTC (permalink / raw)
To: mathias.nyman; +Cc: linux-usb, Niklas Neronin
Rename the Host Controller USB Port Register Set pointer in the 'xhci_port'
struct from "addr" to "port_reg". This new name accurately reflects the
purpose of the pointer.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-debugfs.c | 4 +-
drivers/usb/host/xhci-hub.c | 84 ++++++++++++++++-----------------
drivers/usb/host/xhci-mem.c | 2 +-
drivers/usb/host/xhci-pci.c | 2 +-
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci-tegra.c | 12 ++---
drivers/usb/host/xhci.c | 34 ++++++-------
drivers/usb/host/xhci.h | 2 +-
8 files changed, 71 insertions(+), 71 deletions(-)
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 134b53ae01ce..081c4af5576b 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -329,7 +329,7 @@ static int xhci_portsc_show(struct seq_file *s, void *unused)
u32 portsc;
char str[XHCI_MSG_MAX];
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
seq_printf(s, "%s\n", xhci_decode_portsc(str, portsc));
return 0;
@@ -359,7 +359,7 @@ static ssize_t xhci_port_write(struct file *file, const char __user *ubuf,
return count;
spin_lock_irqsave(&xhci->lock, flags);
/* compliance mode can only be enabled on ports in RxDetect */
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
spin_unlock_irqrestore(&xhci->lock, flags);
return -EPERM;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 15e790e992b3..104809f3df43 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -299,7 +299,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
*/
memset(port_removable, 0, sizeof(port_removable));
for (i = 0; i < ports; i++) {
- portsc = readl(&rhub->ports[i]->addr->portsc);
+ portsc = readl(&rhub->ports[i]->port_reg->portsc);
/* If a device is removable, PORTSC reports a 0, same as in the
* hub descriptor DeviceRemovable bits.
*/
@@ -356,7 +356,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
port_removable = 0;
/* bit 0 is reserved, bit 1 is for port 1, etc. */
for (i = 0; i < ports; i++) {
- portsc = readl(&rhub->ports[i]->addr->portsc);
+ portsc = readl(&rhub->ports[i]->port_reg->portsc);
if (portsc & PORT_DEV_REMOVE)
port_removable |= 1 << (i + 1);
}
@@ -566,13 +566,13 @@ static void xhci_disable_port(struct xhci_hcd *xhci, struct xhci_port *port)
return;
}
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
portsc = xhci_port_state_to_neutral(portsc);
/* Write 1 to disable the port */
xhci_set_portsc(port, portsc | PORT_PE);
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "disable port %d-%d, portsc: 0x%x\n",
hcd->self.busnum, port->hcd_portnum + 1, portsc);
}
@@ -622,7 +622,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
}
/* Change bits are all write 1 to clear */
xhci_set_portsc(port, port_status | status);
- port_status = readl(&port->addr->portsc);
+ port_status = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "clear port%d %s change, portsc: 0x%x\n",
wIndex + 1, port_change_bit, port_status);
@@ -650,7 +650,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
u32 temp;
hcd = port->rhub->hcd;
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "set port power %d-%d %s, portsc: 0x%x\n",
hcd->self.busnum, port->hcd_portnum + 1, on ? "ON" : "OFF", temp);
@@ -660,7 +660,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
if (on) {
/* Power on */
xhci_set_portsc(port, temp | PORT_POWER);
- readl(&port->addr->portsc);
+ readl(&port->port_reg->portsc);
} else {
/* Power off */
xhci_set_portsc(port, temp & ~PORT_POWER);
@@ -683,9 +683,9 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
/* xhci only supports test mode for usb2 ports */
port = xhci->usb2_rhub.ports[wIndex];
- temp = readl(&port->addr->portpmsc);
+ temp = readl(&port->port_reg->portpmsc);
temp |= test_mode << PORT_TEST_MODE_SHIFT;
- writel(temp, &port->addr->portpmsc);
+ writel(temp, &port->port_reg->portpmsc);
xhci->test_mode = test_mode;
if (test_mode == USB_TEST_FORCE_ENABLE)
xhci_start(xhci);
@@ -802,7 +802,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
u32 temp;
u32 portsc;
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
temp = xhci_port_state_to_neutral(portsc);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
@@ -818,7 +818,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
{
u32 temp;
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
temp = xhci_port_state_to_neutral(temp);
if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
@@ -845,7 +845,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, struct xhci_port *port,
{
u32 temp;
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if (temp & port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
@@ -1003,7 +1003,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
}
xhci_ring_device(xhci, port->slot_id);
} else {
- int port_status = readl(&port->addr->portsc);
+ int port_status = readl(&port->port_reg->portsc);
xhci_warn(xhci, "Port resume timed out, port %d-%d: 0x%x\n",
hcd->self.busnum, wIndex + 1, port_status);
@@ -1264,7 +1264,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
wIndex--;
port = ports[portnum1 - 1];
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1289,7 +1289,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
retval = -EINVAL;
break;
}
- port_li = readl(&port->addr->portli);
+ port_li = readl(&port->port_reg->portli);
status = xhci_get_ext_port_status(temp, port_li);
put_unaligned_le32(status, &buf[4]);
}
@@ -1310,7 +1310,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
port = ports[portnum1 - 1];
wIndex--;
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1320,7 +1320,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* FIXME: What new port features do we need to support? */
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if ((temp & PORT_PLS_MASK) != XDEV_U0) {
/* Resume the port to U0 first */
xhci_set_link_state(xhci, port, XDEV_U0);
@@ -1332,7 +1332,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
* a port unless the port reports that it is in the
* enabled (PED = ‘1’,PLS < ‘3’) state.
*/
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if ((temp & PORT_PE) == 0 || (temp & PORT_RESET)
|| (temp & PORT_PLS_MASK) >= XDEV_U3) {
xhci_warn(xhci, "USB core suspending port %d-%d not in U0/U1/U2\n",
@@ -1355,11 +1355,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
msleep(10); /* wait device to enter */
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
bus_state->suspended_ports |= 1 << wIndex;
break;
case USB_PORT_FEAT_LINK_STATE:
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
/* Disable port */
if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
xhci_dbg(xhci, "Disable port %d-%d\n",
@@ -1373,7 +1373,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
PORT_OCC | PORT_RC | PORT_PLC |
PORT_CEC;
xhci_set_portsc(port, temp | PORT_PE);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
}
@@ -1382,7 +1382,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_dbg(xhci, "Enable port %d-%d\n",
hcd->self.busnum, portnum1);
xhci_set_link_state(xhci, port, link_state);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
}
@@ -1415,7 +1415,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
hcd->self.busnum, portnum1);
xhci_set_link_state(xhci, port, link_state);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
}
/* Port must be enabled */
@@ -1463,7 +1463,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n",
hcd->self.busnum, portnum1);
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
}
@@ -1481,12 +1481,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
spin_unlock_irqrestore(&xhci->lock, flags);
while (retries--) {
usleep_range(4000, 8000);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if ((temp & PORT_PLS_MASK) == XDEV_U3)
break;
}
spin_lock_irqsave(&xhci->lock, flags);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
bus_state->suspended_ports |= 1 << wIndex;
}
break;
@@ -1503,36 +1503,36 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = (temp | PORT_RESET);
xhci_set_portsc(port, temp);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n",
hcd->self.busnum, portnum1, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
xhci_set_remote_wake_mask(xhci, port, wake_mask);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "set port remote wake mask, actual port %d-%d status = 0x%x\n",
hcd->self.busnum, portnum1, temp);
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
xhci_set_portsc(port, temp);
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
case USB_PORT_FEAT_U1_TIMEOUT:
if (hcd->speed < HCD_USB3)
goto error;
- temp = readl(&port->addr->portpmsc);
+ temp = readl(&port->port_reg->portpmsc);
temp &= ~PORT_U1_TIMEOUT_MASK;
temp |= PORT_U1_TIMEOUT(timeout);
- writel(temp, &port->addr->portpmsc);
+ writel(temp, &port->port_reg->portpmsc);
break;
case USB_PORT_FEAT_U2_TIMEOUT:
if (hcd->speed < HCD_USB3)
goto error;
- temp = readl(&port->addr->portpmsc);
+ temp = readl(&port->port_reg->portpmsc);
temp &= ~PORT_U2_TIMEOUT_MASK;
temp |= PORT_U2_TIMEOUT(timeout);
- writel(temp, &port->addr->portpmsc);
+ writel(temp, &port->port_reg->portpmsc);
break;
case USB_PORT_FEAT_TEST:
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
@@ -1548,7 +1548,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
goto error;
}
/* unblock any posted writes */
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
break;
case ClearPortFeature:
if (!portnum1 || portnum1 > max_ports)
@@ -1557,7 +1557,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
port = ports[portnum1 - 1];
wIndex--;
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1567,7 +1567,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_port_state_to_neutral(temp);
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
- temp = readl(&port->addr->portsc);
+ temp = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n");
xhci_dbg(xhci, "PORTSC %04x\n", temp);
if (temp & PORT_RESET)
@@ -1682,7 +1682,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
/* For each port, did anything change? If so, set that bit in buf. */
for (i = 0; i < max_ports; i++) {
- temp = readl(&ports[i]->addr->portsc);
+ temp = readl(&ports[i]->port_reg->portsc);
if (temp == ~(u32)0) {
xhci_hc_died(xhci);
retval = -ENODEV;
@@ -1751,7 +1751,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
u32 t1, t2;
int retries = 10;
retry:
- t1 = readl(&ports[port_index]->addr->portsc);
+ t1 = readl(&ports[port_index]->port_reg->portsc);
t2 = xhci_port_state_to_neutral(t1);
portsc_buf[port_index] = 0;
@@ -1850,7 +1850,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
{
u32 portsc;
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
/* if any of these are set we are not stuck */
if (portsc & (PORT_CONNECT | PORT_CAS))
@@ -1865,7 +1865,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
portsc |= PORT_WR;
xhci_set_portsc(port, portsc);
/* flush write */
- readl(&port->addr->portsc);
+ readl(&port->port_reg->portsc);
return true;
}
@@ -1912,7 +1912,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
}
port_index = max_ports;
while (port_index--) {
- portsc = readl(&ports[port_index]->addr->portsc);
+ portsc = readl(&ports[port_index]->port_reg->portsc);
/* warm reset CAS limited ports stuck in polling/compliance */
if ((xhci->quirks & XHCI_MISSING_CAS) &&
@@ -1963,7 +1963,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* poll for U0 link state complete, both USB2 and USB3 */
for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) {
- sret = xhci_handshake(&ports[port_index]->addr->portsc, PORT_PLC,
+ sret = xhci_handshake(&ports[port_index]->port_reg->portsc, PORT_PLC,
PORT_PLC, 10 * 1000);
if (sret) {
xhci_warn(xhci, "port %d-%d resume PLC timeout\n",
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bfd8e471d3c2..7a5578a8d009 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2204,7 +2204,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
return -ENOMEM;
for (i = 0; i < num_ports; i++) {
- xhci->hw_ports[i].addr = &xhci->op_regs->port_regs[i];
+ xhci->hw_ports[i].port_reg = &xhci->op_regs->port_regs[i];
xhci->hw_ports[i].hw_portnum = i;
init_completion(&xhci->hw_ports[i].rexit_done);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 74d6a4f31956..736590f0226b 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -891,7 +891,7 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
port = &xhci->hw_ports[i];
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
if ((portsc & PORT_PLS_MASK) != XDEV_U3)
continue;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6241a8d28ab3..8c4a7a1adad9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2023,7 +2023,7 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
hcd = port->rhub->hcd;
bus_state = &port->rhub->bus_state;
hcd_portnum = port->hcd_portnum;
- portsc = readl(&port->addr->portsc);
+ portsc = readl(&port->port_reg->portsc);
xhci_dbg(xhci, "Port change event, %d-%d, id %d, portsc: 0x%x\n",
hcd->self.busnum, hcd_portnum + 1, port_id, portsc);
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 0ee5192f67fa..754e47c7927d 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -1969,7 +1969,7 @@ static bool xhci_hub_ports_suspended(struct xhci_hub *hub)
u32 value;
for (i = 0; i < hub->num_ports; i++) {
- value = readl(&hub->ports[i]->addr->portsc);
+ value = readl(&hub->ports[i]->port_reg->portsc);
if ((value & PORT_PE) == 0)
continue;
@@ -2095,7 +2095,7 @@ static void tegra_xhci_enable_phy_sleepwalk_wake(struct tegra_xusb *tegra)
if (!is_host_mode_phy(tegra, i, j))
continue;
- portsc = readl(&rhub->ports[index]->addr->portsc);
+ portsc = readl(&rhub->ports[index]->port_reg->portsc);
speed = tegra_xhci_portsc_to_speed(tegra, portsc);
tegra_xusb_padctl_enable_phy_sleepwalk(padctl, phy, speed);
tegra_xusb_padctl_enable_phy_wake(padctl, phy);
@@ -2190,7 +2190,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
for (i = 0; i < xhci->usb2_rhub.num_ports; i++) {
if (!xhci->usb2_rhub.ports[i])
continue;
- portsc = readl(&xhci->usb2_rhub.ports[i]->addr->portsc);
+ portsc = readl(&xhci->usb2_rhub.ports[i]->port_reg->portsc);
tegra->lp0_utmi_pad_mask &= ~BIT(i);
if (((portsc & PORT_PLS_MASK) == XDEV_U3) || ((portsc & DEV_SPEED_MASK) == XDEV_FS))
tegra->lp0_utmi_pad_mask |= BIT(i);
@@ -2712,7 +2712,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
while (i--) {
if (!test_bit(i, &bus_state->resuming_ports))
continue;
- portsc = readl(&ports[i]->addr->portsc);
+ portsc = readl(&ports[i]->port_reg->portsc);
if ((portsc & PORT_PLS_MASK) == XDEV_RESUME)
tegra_phy_xusb_utmi_pad_power_on(
tegra_xusb_get_phy(tegra, "usb2", (int) i));
@@ -2730,7 +2730,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
if (!index || index > rhub->num_ports)
return -EPIPE;
ports = rhub->ports;
- portsc = readl(&ports[port]->addr->portsc);
+ portsc = readl(&ports[port]->port_reg->portsc);
if (portsc & PORT_CONNECT)
tegra_phy_xusb_utmi_pad_power_on(phy);
}
@@ -2749,7 +2749,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
if ((type_req == ClearPortFeature) && (value == USB_PORT_FEAT_C_CONNECTION)) {
ports = rhub->ports;
- portsc = readl(&ports[port]->addr->portsc);
+ portsc = readl(&ports[port]->port_reg->portsc);
if (!(portsc & PORT_CONNECT)) {
/* We don't suspend the PAD while HNP role swap happens on the OTG
* port
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 676441dc3141..8b252a2814cc 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -44,7 +44,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
void xhci_set_portsc(struct xhci_port *port, u32 val)
{
trace_xhci_set_portsc(port, val);
- writel(val, &port->addr->portsc);
+ writel(val, &port->port_reg->portsc);
}
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
@@ -377,7 +377,7 @@ static void compliance_mode_recovery(struct timer_list *t)
return;
for (i = 0; i < rhub->num_ports; i++) {
- temp = readl(&rhub->ports[i]->addr->portsc);
+ temp = readl(&rhub->ports[i]->port_reg->portsc);
if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
/*
* Compliance Mode Detected. Letting USB Core
@@ -900,7 +900,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
spin_lock_irqsave(&xhci->lock, flags);
for (i = 0; i < rhub->num_ports; i++) {
- portsc = readl(&rhub->ports[i]->addr->portsc);
+ portsc = readl(&rhub->ports[i]->port_reg->portsc);
t1 = xhci_port_state_to_neutral(portsc);
t2 = t1;
@@ -940,7 +940,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb2_rhub.num_ports;
ports = xhci->usb2_rhub.ports;
while (port_index--) {
- portsc = readl(&ports[port_index]->addr->portsc);
+ portsc = readl(&ports[port_index]->port_reg->portsc);
if (portsc & PORT_CHANGE_MASK ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -948,7 +948,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb3_rhub.num_ports;
ports = xhci->usb3_rhub.ports;
while (port_index--) {
- portsc = readl(&ports[port_index]->addr->portsc);
+ portsc = readl(&ports[port_index]->port_reg->portsc);
if (portsc & (PORT_CHANGE_MASK | PORT_CAS) ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -4619,7 +4619,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_port **ports;
- struct xhci_port_regs __iomem *port_regs;
+ struct xhci_port_regs __iomem *port_reg;
u32 pm_val, hlpm_val, field;
unsigned int port_num;
unsigned long flags;
@@ -4644,8 +4644,8 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
ports = xhci->usb2_rhub.ports;
port_num = udev->portnum - 1;
- port_regs = ports[port_num]->addr;
- pm_val = readl(&port_regs->portpmsc);
+ port_reg = ports[port_num]->port_reg;
+ pm_val = readl(&port_reg->portpmsc);
xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
str_enable_disable(enable), port_num + 1);
@@ -4674,30 +4674,30 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev);
- writel(hlpm_val, &port_regs->porthlmpc);
+ writel(hlpm_val, &port_reg->porthlmpc);
/* flush write */
- readl(&port_regs->porthlmpc);
+ readl(&port_reg->porthlmpc);
} else {
hird = xhci_calculate_hird_besl(xhci, udev);
}
pm_val &= ~PORT_HIRD_MASK;
pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
- writel(pm_val, &port_regs->portpmsc);
- pm_val = readl(&port_regs->portpmsc);
+ writel(pm_val, &port_reg->portpmsc);
+ pm_val = readl(&port_reg->portpmsc);
pm_val |= PORT_HLE;
- writel(pm_val, &port_regs->portpmsc);
+ writel(pm_val, &port_reg->portpmsc);
/* flush write */
- readl(&port_regs->portpmsc);
+ readl(&port_reg->portpmsc);
} else {
pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
- writel(pm_val, &port_regs->portpmsc);
+ writel(pm_val, &port_reg->portpmsc);
/* flush write */
- readl(&port_regs->portpmsc);
+ readl(&port_reg->portpmsc);
if (udev->usb2_hw_lpm_besl_capable) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_change_max_exit_latency(xhci, udev, 0);
- readl_poll_timeout(&ports[port_num]->addr->portsc, pm_val,
+ readl_poll_timeout(&ports[port_num]->port_reg->portsc, pm_val,
(pm_val & PORT_PLS_MASK) == XDEV_U0,
100, 10000);
return 0;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 38edc430ee49..1cfdb8f26122 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1464,7 +1464,7 @@ struct xhci_port_cap {
};
struct xhci_port {
- struct xhci_port_regs __iomem *addr;
+ struct xhci_port_regs __iomem *port_reg;
int hw_portnum;
int hcd_portnum;
struct xhci_hub *rhub;
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 0/7] usb: xhci: Port Register Set improvements
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
` (6 preceding siblings ...)
2025-09-04 15:42 ` [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port' Niklas Neronin
@ 2025-09-05 1:57 ` Peter Chen (CIX)
2025-09-10 7:12 ` Neronin, Niklas
7 siblings, 1 reply; 13+ messages in thread
From: Peter Chen (CIX) @ 2025-09-05 1:57 UTC (permalink / raw)
To: Niklas Neronin; +Cc: mathias.nyman, linux-usb
On 25-09-04 17:42:13, Niklas Neronin wrote:
> The aim of this patch set is to introduce tracing for PORTCS writes and
I find several patches you are using PORTCS instead of PORTSC, is it typo?
Peter
> implement a Port Register Set struct.
>
> Introduces a new struct for the Host Controller USB Port Register Set.
> The current implementation accesses these registers through a single
> '__le32' pointer, which, in conjunction with a macro, navigates to the
> specific register using (base address + offset).
>
> Currently, how its accessed | Register Name
> --------------------------------------------------------------------------
> port->addr | Port Status and Control
> port->addr + PORTPMSC | Port Power Management Status and Control
> port->addr + PORTLI | Port Link Info
> port->addr + PORTHLPMC | Port Hardware LPM Control
>
>
> After, how its accessed | Register Name
> --------------------------------------------------------------------------
> port->port_reg->portsc | Port Status and Control
> port->port_reg->portpmsc | Port Power Management Status and Control
> port->port_reg->portli | Port Link Info
> port->port_reg->porthlmpc | Port Hardware LPM Control
>
> These changes make it easier for future modification and their review.
>
> Note:
> I have chosen to split the struct changes across three separate commits
> due to the substantial number of modified lines. Personally, I find that
> minor typos are more likely to occur when dealing with larger patches.
> However, I am open to consolidating these patches into a single commit
> after review.
>
> Niklas Neronin (7):
> usb: xhci: correct indentation for PORTCS tracing function
> usb: xhci: align PORTCS trace with one-based port numbering
> usb: xhci: improve xhci_decode_portsc()
> usb: xhci: add tracing for PORTCS register writes
> usb: xhci: add USB Port Register Set struct
> usb: xhci: implement USB Port Register Set struct
> usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
>
> drivers/usb/host/xhci-debugfs.c | 6 +-
> drivers/usb/host/xhci-hub.c | 115 ++++++++++++++++----------------
> drivers/usb/host/xhci-mem.c | 3 +-
> drivers/usb/host/xhci-pci.c | 4 +-
> drivers/usb/host/xhci-ring.c | 2 +-
> drivers/usb/host/xhci-tegra.c | 12 ++--
> drivers/usb/host/xhci-trace.h | 39 ++++++-----
> drivers/usb/host/xhci.c | 41 +++++++-----
> drivers/usb/host/xhci.h | 94 +++++++++++++-------------
> 9 files changed, 161 insertions(+), 155 deletions(-)
>
> --
> 2.50.1
>
>
--
Best regards,
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
2025-09-04 15:42 ` [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port' Niklas Neronin
@ 2025-09-05 2:40 ` Peter Chen (CIX)
2025-09-10 7:24 ` Neronin, Niklas
0 siblings, 1 reply; 13+ messages in thread
From: Peter Chen (CIX) @ 2025-09-05 2:40 UTC (permalink / raw)
To: Niklas Neronin; +Cc: mathias.nyman, linux-usb
On 25-09-04 17:42:20, Niklas Neronin wrote:
> Rename the Host Controller USB Port Register Set pointer in the 'xhci_port'
> struct from "addr" to "port_reg". This new name accurately reflects the
> purpose of the pointer.
>
I am also implementing a wrapper that needs to cover all PORTSC
registers access, it is used to cover the controllers which have some
problems to access PORTSC when the USB PHY switches to DP for USB/DP
altmode scenario, current USB core and xHCI core access USB3 PORTSC
at some places (detail could see the changes you do below) if controller
supports both USB2 and USB3, even the USB3 connection is not there.
I am thinking is it possible you add a wrapper like
xhci_port_readl/xhci_port_writel for all PORTSC access, otherwise I
also need to change all places you make.
Peter
> Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
> ---
> drivers/usb/host/xhci-debugfs.c | 4 +-
> drivers/usb/host/xhci-hub.c | 84 ++++++++++++++++-----------------
> drivers/usb/host/xhci-mem.c | 2 +-
> drivers/usb/host/xhci-pci.c | 2 +-
> drivers/usb/host/xhci-ring.c | 2 +-
> drivers/usb/host/xhci-tegra.c | 12 ++---
> drivers/usb/host/xhci.c | 34 ++++++-------
> drivers/usb/host/xhci.h | 2 +-
> 8 files changed, 71 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
> index 134b53ae01ce..081c4af5576b 100644
> --- a/drivers/usb/host/xhci-debugfs.c
> +++ b/drivers/usb/host/xhci-debugfs.c
> @@ -329,7 +329,7 @@ static int xhci_portsc_show(struct seq_file *s, void *unused)
> u32 portsc;
> char str[XHCI_MSG_MAX];
>
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
> seq_printf(s, "%s\n", xhci_decode_portsc(str, portsc));
>
> return 0;
> @@ -359,7 +359,7 @@ static ssize_t xhci_port_write(struct file *file, const char __user *ubuf,
> return count;
> spin_lock_irqsave(&xhci->lock, flags);
> /* compliance mode can only be enabled on ports in RxDetect */
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
> if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
> spin_unlock_irqrestore(&xhci->lock, flags);
> return -EPERM;
> diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
> index 15e790e992b3..104809f3df43 100644
> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -299,7 +299,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
> */
> memset(port_removable, 0, sizeof(port_removable));
> for (i = 0; i < ports; i++) {
> - portsc = readl(&rhub->ports[i]->addr->portsc);
> + portsc = readl(&rhub->ports[i]->port_reg->portsc);
> /* If a device is removable, PORTSC reports a 0, same as in the
> * hub descriptor DeviceRemovable bits.
> */
> @@ -356,7 +356,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
> port_removable = 0;
> /* bit 0 is reserved, bit 1 is for port 1, etc. */
> for (i = 0; i < ports; i++) {
> - portsc = readl(&rhub->ports[i]->addr->portsc);
> + portsc = readl(&rhub->ports[i]->port_reg->portsc);
> if (portsc & PORT_DEV_REMOVE)
> port_removable |= 1 << (i + 1);
> }
> @@ -566,13 +566,13 @@ static void xhci_disable_port(struct xhci_hcd *xhci, struct xhci_port *port)
> return;
> }
>
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
> portsc = xhci_port_state_to_neutral(portsc);
>
> /* Write 1 to disable the port */
> xhci_set_portsc(port, portsc | PORT_PE);
>
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
> xhci_dbg(xhci, "disable port %d-%d, portsc: 0x%x\n",
> hcd->self.busnum, port->hcd_portnum + 1, portsc);
> }
> @@ -622,7 +622,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
> }
> /* Change bits are all write 1 to clear */
> xhci_set_portsc(port, port_status | status);
> - port_status = readl(&port->addr->portsc);
> + port_status = readl(&port->port_reg->portsc);
>
> xhci_dbg(xhci, "clear port%d %s change, portsc: 0x%x\n",
> wIndex + 1, port_change_bit, port_status);
> @@ -650,7 +650,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
> u32 temp;
>
> hcd = port->rhub->hcd;
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
>
> xhci_dbg(xhci, "set port power %d-%d %s, portsc: 0x%x\n",
> hcd->self.busnum, port->hcd_portnum + 1, on ? "ON" : "OFF", temp);
> @@ -660,7 +660,7 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port,
> if (on) {
> /* Power on */
> xhci_set_portsc(port, temp | PORT_POWER);
> - readl(&port->addr->portsc);
> + readl(&port->port_reg->portsc);
> } else {
> /* Power off */
> xhci_set_portsc(port, temp & ~PORT_POWER);
> @@ -683,9 +683,9 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
>
> /* xhci only supports test mode for usb2 ports */
> port = xhci->usb2_rhub.ports[wIndex];
> - temp = readl(&port->addr->portpmsc);
> + temp = readl(&port->port_reg->portpmsc);
> temp |= test_mode << PORT_TEST_MODE_SHIFT;
> - writel(temp, &port->addr->portpmsc);
> + writel(temp, &port->port_reg->portpmsc);
> xhci->test_mode = test_mode;
> if (test_mode == USB_TEST_FORCE_ENABLE)
> xhci_start(xhci);
> @@ -802,7 +802,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
> u32 temp;
> u32 portsc;
>
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
> temp = xhci_port_state_to_neutral(portsc);
> temp &= ~PORT_PLS_MASK;
> temp |= PORT_LINK_STROBE | link_state;
> @@ -818,7 +818,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
> {
> u32 temp;
>
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> temp = xhci_port_state_to_neutral(temp);
>
> if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
> @@ -845,7 +845,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, struct xhci_port *port,
> {
> u32 temp;
>
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if (temp & port_bit) {
> temp = xhci_port_state_to_neutral(temp);
> temp |= port_bit;
> @@ -1003,7 +1003,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
> }
> xhci_ring_device(xhci, port->slot_id);
> } else {
> - int port_status = readl(&port->addr->portsc);
> + int port_status = readl(&port->port_reg->portsc);
>
> xhci_warn(xhci, "Port resume timed out, port %d-%d: 0x%x\n",
> hcd->self.busnum, wIndex + 1, port_status);
> @@ -1264,7 +1264,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>
> wIndex--;
> port = ports[portnum1 - 1];
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if (temp == ~(u32)0) {
> xhci_hc_died(xhci);
> retval = -ENODEV;
> @@ -1289,7 +1289,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> retval = -EINVAL;
> break;
> }
> - port_li = readl(&port->addr->portli);
> + port_li = readl(&port->port_reg->portli);
> status = xhci_get_ext_port_status(temp, port_li);
> put_unaligned_le32(status, &buf[4]);
> }
> @@ -1310,7 +1310,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>
> port = ports[portnum1 - 1];
> wIndex--;
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if (temp == ~(u32)0) {
> xhci_hc_died(xhci);
> retval = -ENODEV;
> @@ -1320,7 +1320,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> /* FIXME: What new port features do we need to support? */
> switch (wValue) {
> case USB_PORT_FEAT_SUSPEND:
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if ((temp & PORT_PLS_MASK) != XDEV_U0) {
> /* Resume the port to U0 first */
> xhci_set_link_state(xhci, port, XDEV_U0);
> @@ -1332,7 +1332,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> * a port unless the port reports that it is in the
> * enabled (PED = ‘1’,PLS < ‘3’) state.
> */
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if ((temp & PORT_PE) == 0 || (temp & PORT_RESET)
> || (temp & PORT_PLS_MASK) >= XDEV_U3) {
> xhci_warn(xhci, "USB core suspending port %d-%d not in U0/U1/U2\n",
> @@ -1355,11 +1355,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> msleep(10); /* wait device to enter */
> spin_lock_irqsave(&xhci->lock, flags);
>
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> bus_state->suspended_ports |= 1 << wIndex;
> break;
> case USB_PORT_FEAT_LINK_STATE:
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> /* Disable port */
> if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
> xhci_dbg(xhci, "Disable port %d-%d\n",
> @@ -1373,7 +1373,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> PORT_OCC | PORT_RC | PORT_PLC |
> PORT_CEC;
> xhci_set_portsc(port, temp | PORT_PE);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> }
>
> @@ -1382,7 +1382,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> xhci_dbg(xhci, "Enable port %d-%d\n",
> hcd->self.busnum, portnum1);
> xhci_set_link_state(xhci, port, link_state);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> }
>
> @@ -1415,7 +1415,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> hcd->self.busnum, portnum1);
> xhci_set_link_state(xhci, port, link_state);
>
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> }
> /* Port must be enabled */
> @@ -1463,7 +1463,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n",
> hcd->self.busnum, portnum1);
> spin_lock_irqsave(&xhci->lock, flags);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> }
>
> @@ -1481,12 +1481,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> spin_unlock_irqrestore(&xhci->lock, flags);
> while (retries--) {
> usleep_range(4000, 8000);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if ((temp & PORT_PLS_MASK) == XDEV_U3)
> break;
> }
> spin_lock_irqsave(&xhci->lock, flags);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> bus_state->suspended_ports |= 1 << wIndex;
> }
> break;
> @@ -1503,36 +1503,36 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> temp = (temp | PORT_RESET);
> xhci_set_portsc(port, temp);
>
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n",
> hcd->self.busnum, portnum1, temp);
> break;
> case USB_PORT_FEAT_REMOTE_WAKE_MASK:
> xhci_set_remote_wake_mask(xhci, port, wake_mask);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> xhci_dbg(xhci, "set port remote wake mask, actual port %d-%d status = 0x%x\n",
> hcd->self.busnum, portnum1, temp);
> break;
> case USB_PORT_FEAT_BH_PORT_RESET:
> temp |= PORT_WR;
> xhci_set_portsc(port, temp);
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> case USB_PORT_FEAT_U1_TIMEOUT:
> if (hcd->speed < HCD_USB3)
> goto error;
> - temp = readl(&port->addr->portpmsc);
> + temp = readl(&port->port_reg->portpmsc);
> temp &= ~PORT_U1_TIMEOUT_MASK;
> temp |= PORT_U1_TIMEOUT(timeout);
> - writel(temp, &port->addr->portpmsc);
> + writel(temp, &port->port_reg->portpmsc);
> break;
> case USB_PORT_FEAT_U2_TIMEOUT:
> if (hcd->speed < HCD_USB3)
> goto error;
> - temp = readl(&port->addr->portpmsc);
> + temp = readl(&port->port_reg->portpmsc);
> temp &= ~PORT_U2_TIMEOUT_MASK;
> temp |= PORT_U2_TIMEOUT(timeout);
> - writel(temp, &port->addr->portpmsc);
> + writel(temp, &port->port_reg->portpmsc);
> break;
> case USB_PORT_FEAT_TEST:
> /* 4.19.6 Port Test Modes (USB2 Test Mode) */
> @@ -1548,7 +1548,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> goto error;
> }
> /* unblock any posted writes */
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> break;
> case ClearPortFeature:
> if (!portnum1 || portnum1 > max_ports)
> @@ -1557,7 +1557,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> port = ports[portnum1 - 1];
>
> wIndex--;
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> if (temp == ~(u32)0) {
> xhci_hc_died(xhci);
> retval = -ENODEV;
> @@ -1567,7 +1567,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> temp = xhci_port_state_to_neutral(temp);
> switch (wValue) {
> case USB_PORT_FEAT_SUSPEND:
> - temp = readl(&port->addr->portsc);
> + temp = readl(&port->port_reg->portsc);
> xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n");
> xhci_dbg(xhci, "PORTSC %04x\n", temp);
> if (temp & PORT_RESET)
> @@ -1682,7 +1682,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
>
> /* For each port, did anything change? If so, set that bit in buf. */
> for (i = 0; i < max_ports; i++) {
> - temp = readl(&ports[i]->addr->portsc);
> + temp = readl(&ports[i]->port_reg->portsc);
> if (temp == ~(u32)0) {
> xhci_hc_died(xhci);
> retval = -ENODEV;
> @@ -1751,7 +1751,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
> u32 t1, t2;
> int retries = 10;
> retry:
> - t1 = readl(&ports[port_index]->addr->portsc);
> + t1 = readl(&ports[port_index]->port_reg->portsc);
> t2 = xhci_port_state_to_neutral(t1);
> portsc_buf[port_index] = 0;
>
> @@ -1850,7 +1850,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
> {
> u32 portsc;
>
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
>
> /* if any of these are set we are not stuck */
> if (portsc & (PORT_CONNECT | PORT_CAS))
> @@ -1865,7 +1865,7 @@ static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
> portsc |= PORT_WR;
> xhci_set_portsc(port, portsc);
> /* flush write */
> - readl(&port->addr->portsc);
> + readl(&port->port_reg->portsc);
> return true;
> }
>
> @@ -1912,7 +1912,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
> }
> port_index = max_ports;
> while (port_index--) {
> - portsc = readl(&ports[port_index]->addr->portsc);
> + portsc = readl(&ports[port_index]->port_reg->portsc);
>
> /* warm reset CAS limited ports stuck in polling/compliance */
> if ((xhci->quirks & XHCI_MISSING_CAS) &&
> @@ -1963,7 +1963,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
>
> /* poll for U0 link state complete, both USB2 and USB3 */
> for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) {
> - sret = xhci_handshake(&ports[port_index]->addr->portsc, PORT_PLC,
> + sret = xhci_handshake(&ports[port_index]->port_reg->portsc, PORT_PLC,
> PORT_PLC, 10 * 1000);
> if (sret) {
> xhci_warn(xhci, "port %d-%d resume PLC timeout\n",
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index bfd8e471d3c2..7a5578a8d009 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -2204,7 +2204,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
> return -ENOMEM;
>
> for (i = 0; i < num_ports; i++) {
> - xhci->hw_ports[i].addr = &xhci->op_regs->port_regs[i];
> + xhci->hw_ports[i].port_reg = &xhci->op_regs->port_regs[i];
> xhci->hw_ports[i].hw_portnum = i;
>
> init_completion(&xhci->hw_ports[i].rexit_done);
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 74d6a4f31956..736590f0226b 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -891,7 +891,7 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
>
> for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
> port = &xhci->hw_ports[i];
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
>
> if ((portsc & PORT_PLS_MASK) != XDEV_U3)
> continue;
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 6241a8d28ab3..8c4a7a1adad9 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -2023,7 +2023,7 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
> hcd = port->rhub->hcd;
> bus_state = &port->rhub->bus_state;
> hcd_portnum = port->hcd_portnum;
> - portsc = readl(&port->addr->portsc);
> + portsc = readl(&port->port_reg->portsc);
>
> xhci_dbg(xhci, "Port change event, %d-%d, id %d, portsc: 0x%x\n",
> hcd->self.busnum, hcd_portnum + 1, port_id, portsc);
> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
> index 0ee5192f67fa..754e47c7927d 100644
> --- a/drivers/usb/host/xhci-tegra.c
> +++ b/drivers/usb/host/xhci-tegra.c
> @@ -1969,7 +1969,7 @@ static bool xhci_hub_ports_suspended(struct xhci_hub *hub)
> u32 value;
>
> for (i = 0; i < hub->num_ports; i++) {
> - value = readl(&hub->ports[i]->addr->portsc);
> + value = readl(&hub->ports[i]->port_reg->portsc);
> if ((value & PORT_PE) == 0)
> continue;
>
> @@ -2095,7 +2095,7 @@ static void tegra_xhci_enable_phy_sleepwalk_wake(struct tegra_xusb *tegra)
> if (!is_host_mode_phy(tegra, i, j))
> continue;
>
> - portsc = readl(&rhub->ports[index]->addr->portsc);
> + portsc = readl(&rhub->ports[index]->port_reg->portsc);
> speed = tegra_xhci_portsc_to_speed(tegra, portsc);
> tegra_xusb_padctl_enable_phy_sleepwalk(padctl, phy, speed);
> tegra_xusb_padctl_enable_phy_wake(padctl, phy);
> @@ -2190,7 +2190,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
> for (i = 0; i < xhci->usb2_rhub.num_ports; i++) {
> if (!xhci->usb2_rhub.ports[i])
> continue;
> - portsc = readl(&xhci->usb2_rhub.ports[i]->addr->portsc);
> + portsc = readl(&xhci->usb2_rhub.ports[i]->port_reg->portsc);
> tegra->lp0_utmi_pad_mask &= ~BIT(i);
> if (((portsc & PORT_PLS_MASK) == XDEV_U3) || ((portsc & DEV_SPEED_MASK) == XDEV_FS))
> tegra->lp0_utmi_pad_mask |= BIT(i);
> @@ -2712,7 +2712,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
> while (i--) {
> if (!test_bit(i, &bus_state->resuming_ports))
> continue;
> - portsc = readl(&ports[i]->addr->portsc);
> + portsc = readl(&ports[i]->port_reg->portsc);
> if ((portsc & PORT_PLS_MASK) == XDEV_RESUME)
> tegra_phy_xusb_utmi_pad_power_on(
> tegra_xusb_get_phy(tegra, "usb2", (int) i));
> @@ -2730,7 +2730,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
> if (!index || index > rhub->num_ports)
> return -EPIPE;
> ports = rhub->ports;
> - portsc = readl(&ports[port]->addr->portsc);
> + portsc = readl(&ports[port]->port_reg->portsc);
> if (portsc & PORT_CONNECT)
> tegra_phy_xusb_utmi_pad_power_on(phy);
> }
> @@ -2749,7 +2749,7 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value,
>
> if ((type_req == ClearPortFeature) && (value == USB_PORT_FEAT_C_CONNECTION)) {
> ports = rhub->ports;
> - portsc = readl(&ports[port]->addr->portsc);
> + portsc = readl(&ports[port]->port_reg->portsc);
> if (!(portsc & PORT_CONNECT)) {
> /* We don't suspend the PAD while HNP role swap happens on the OTG
> * port
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 676441dc3141..8b252a2814cc 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -44,7 +44,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
> void xhci_set_portsc(struct xhci_port *port, u32 val)
> {
> trace_xhci_set_portsc(port, val);
> - writel(val, &port->addr->portsc);
> + writel(val, &port->port_reg->portsc);
> }
>
> static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
> @@ -377,7 +377,7 @@ static void compliance_mode_recovery(struct timer_list *t)
> return;
>
> for (i = 0; i < rhub->num_ports; i++) {
> - temp = readl(&rhub->ports[i]->addr->portsc);
> + temp = readl(&rhub->ports[i]->port_reg->portsc);
> if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
> /*
> * Compliance Mode Detected. Letting USB Core
> @@ -900,7 +900,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
> spin_lock_irqsave(&xhci->lock, flags);
>
> for (i = 0; i < rhub->num_ports; i++) {
> - portsc = readl(&rhub->ports[i]->addr->portsc);
> + portsc = readl(&rhub->ports[i]->port_reg->portsc);
> t1 = xhci_port_state_to_neutral(portsc);
> t2 = t1;
>
> @@ -940,7 +940,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
> port_index = xhci->usb2_rhub.num_ports;
> ports = xhci->usb2_rhub.ports;
> while (port_index--) {
> - portsc = readl(&ports[port_index]->addr->portsc);
> + portsc = readl(&ports[port_index]->port_reg->portsc);
> if (portsc & PORT_CHANGE_MASK ||
> (portsc & PORT_PLS_MASK) == XDEV_RESUME)
> return true;
> @@ -948,7 +948,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
> port_index = xhci->usb3_rhub.num_ports;
> ports = xhci->usb3_rhub.ports;
> while (port_index--) {
> - portsc = readl(&ports[port_index]->addr->portsc);
> + portsc = readl(&ports[port_index]->port_reg->portsc);
> if (portsc & (PORT_CHANGE_MASK | PORT_CAS) ||
> (portsc & PORT_PLS_MASK) == XDEV_RESUME)
> return true;
> @@ -4619,7 +4619,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
> {
> struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> struct xhci_port **ports;
> - struct xhci_port_regs __iomem *port_regs;
> + struct xhci_port_regs __iomem *port_reg;
> u32 pm_val, hlpm_val, field;
> unsigned int port_num;
> unsigned long flags;
> @@ -4644,8 +4644,8 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
>
> ports = xhci->usb2_rhub.ports;
> port_num = udev->portnum - 1;
> - port_regs = ports[port_num]->addr;
> - pm_val = readl(&port_regs->portpmsc);
> + port_reg = ports[port_num]->port_reg;
> + pm_val = readl(&port_reg->portpmsc);
>
> xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
> str_enable_disable(enable), port_num + 1);
> @@ -4674,30 +4674,30 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
> spin_lock_irqsave(&xhci->lock, flags);
>
> hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev);
> - writel(hlpm_val, &port_regs->porthlmpc);
> + writel(hlpm_val, &port_reg->porthlmpc);
> /* flush write */
> - readl(&port_regs->porthlmpc);
> + readl(&port_reg->porthlmpc);
> } else {
> hird = xhci_calculate_hird_besl(xhci, udev);
> }
>
> pm_val &= ~PORT_HIRD_MASK;
> pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
> - writel(pm_val, &port_regs->portpmsc);
> - pm_val = readl(&port_regs->portpmsc);
> + writel(pm_val, &port_reg->portpmsc);
> + pm_val = readl(&port_reg->portpmsc);
> pm_val |= PORT_HLE;
> - writel(pm_val, &port_regs->portpmsc);
> + writel(pm_val, &port_reg->portpmsc);
> /* flush write */
> - readl(&port_regs->portpmsc);
> + readl(&port_reg->portpmsc);
> } else {
> pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
> - writel(pm_val, &port_regs->portpmsc);
> + writel(pm_val, &port_reg->portpmsc);
> /* flush write */
> - readl(&port_regs->portpmsc);
> + readl(&port_reg->portpmsc);
> if (udev->usb2_hw_lpm_besl_capable) {
> spin_unlock_irqrestore(&xhci->lock, flags);
> xhci_change_max_exit_latency(xhci, udev, 0);
> - readl_poll_timeout(&ports[port_num]->addr->portsc, pm_val,
> + readl_poll_timeout(&ports[port_num]->port_reg->portsc, pm_val,
> (pm_val & PORT_PLS_MASK) == XDEV_U0,
> 100, 10000);
> return 0;
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 38edc430ee49..1cfdb8f26122 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1464,7 +1464,7 @@ struct xhci_port_cap {
> };
>
> struct xhci_port {
> - struct xhci_port_regs __iomem *addr;
> + struct xhci_port_regs __iomem *port_reg;
> int hw_portnum;
> int hcd_portnum;
> struct xhci_hub *rhub;
> --
> 2.50.1
>
>
--
Best regards,
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/7] usb: xhci: Port Register Set improvements
2025-09-05 1:57 ` [PATCH 0/7] usb: xhci: Port Register Set improvements Peter Chen (CIX)
@ 2025-09-10 7:12 ` Neronin, Niklas
0 siblings, 0 replies; 13+ messages in thread
From: Neronin, Niklas @ 2025-09-10 7:12 UTC (permalink / raw)
To: Peter Chen (CIX); +Cc: mathias.nyman, linux-usb
On 05/09/2025 4.57, Peter Chen (CIX) wrote:
> On 25-09-04 17:42:13, Niklas Neronin wrote:
>> The aim of this patch set is to introduce tracing for PORTCS writes and
>
> I find several patches you are using PORTCS instead of PORTSC, is it typo?
>
Yes, it should be "PORTSC" (Port Status and Control). Good catch thanks!
Best Regards,
Niklas
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
2025-09-05 2:40 ` Peter Chen (CIX)
@ 2025-09-10 7:24 ` Neronin, Niklas
2025-09-12 0:48 ` Peter Chen (CIX)
0 siblings, 1 reply; 13+ messages in thread
From: Neronin, Niklas @ 2025-09-10 7:24 UTC (permalink / raw)
To: Peter Chen (CIX); +Cc: mathias.nyman, linux-usb
On 05/09/2025 5.40, Peter Chen (CIX) wrote:
> On 25-09-04 17:42:20, Niklas Neronin wrote:
>> Rename the Host Controller USB Port Register Set pointer in the 'xhci_port'
>> struct from "addr" to "port_reg". This new name accurately reflects the
>> purpose of the pointer.
>>
>
> I am also implementing a wrapper that needs to cover all PORTSC
> registers access, it is used to cover the controllers which have some
> problems to access PORTSC when the USB PHY switches to DP for USB/DP
> altmode scenario, current USB core and xHCI core access USB3 PORTSC
> at some places (detail could see the changes you do below) if controller
> supports both USB2 and USB3, even the USB3 connection is not there.
>
> I am thinking is it possible you add a wrapper like
> xhci_port_readl/xhci_port_writel for all PORTSC access, otherwise I
> also need to change all places you make.
>
Yes, I will add a read PORTSC functions, in version 2.
I am on vacation this week, so v2 will be ready next week.
Best Regards,
Niklas
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port'
2025-09-10 7:24 ` Neronin, Niklas
@ 2025-09-12 0:48 ` Peter Chen (CIX)
0 siblings, 0 replies; 13+ messages in thread
From: Peter Chen (CIX) @ 2025-09-12 0:48 UTC (permalink / raw)
To: Neronin, Niklas; +Cc: mathias.nyman, linux-usb
On 25-09-10 10:24:37, Neronin, Niklas wrote:
>
>
> On 05/09/2025 5.40, Peter Chen (CIX) wrote:
> > On 25-09-04 17:42:20, Niklas Neronin wrote:
> >> Rename the Host Controller USB Port Register Set pointer in the 'xhci_port'
> >> struct from "addr" to "port_reg". This new name accurately reflects the
> >> purpose of the pointer.
> >>
> >
> > I am also implementing a wrapper that needs to cover all PORTSC
> > registers access, it is used to cover the controllers which have some
> > problems to access PORTSC when the USB PHY switches to DP for USB/DP
> > altmode scenario, current USB core and xHCI core access USB3 PORTSC
> > at some places (detail could see the changes you do below) if controller
> > supports both USB2 and USB3, even the USB3 connection is not there.
> >
> > I am thinking is it possible you add a wrapper like
> > xhci_port_readl/xhci_port_writel for all PORTSC access, otherwise I
> > also need to change all places you make.
> >
>
> Yes, I will add a read PORTSC functions, in version 2.
> I am on vacation this week, so v2 will be ready next week.
>
Thanks, it is also a good place if we would like to track LTSSM change.
--
Best regards,
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-09-12 0:48 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-04 15:42 [PATCH 0/7] usb: xhci: Port Register Set improvements Niklas Neronin
2025-09-04 15:42 ` [PATCH 1/7] usb: xhci: correct indentation for PORTCS tracing function Niklas Neronin
2025-09-04 15:42 ` [PATCH 2/7] usb: xhci: align PORTCS trace with one-based port numbering Niklas Neronin
2025-09-04 15:42 ` [PATCH 3/7] usb: xhci: improve xhci_decode_portsc() Niklas Neronin
2025-09-04 15:42 ` [PATCH 4/7] usb: xhci: add tracing for PORTCS register writes Niklas Neronin
2025-09-04 15:42 ` [PATCH 5/7] usb: xhci: add USB Port Register Set struct Niklas Neronin
2025-09-04 15:42 ` [PATCH 6/7] usb: xhci: implement " Niklas Neronin
2025-09-04 15:42 ` [PATCH 7/7] usb: xhci: rename Port Register Set pointer in struct 'xhci_port' Niklas Neronin
2025-09-05 2:40 ` Peter Chen (CIX)
2025-09-10 7:24 ` Neronin, Niklas
2025-09-12 0:48 ` Peter Chen (CIX)
2025-09-05 1:57 ` [PATCH 0/7] usb: xhci: Port Register Set improvements Peter Chen (CIX)
2025-09-10 7:12 ` Neronin, Niklas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox