usb: xhci: implement USB Port Register Set struct

Previously, each port's 'addr' field pointed to the base of the Host
Controller USB Port Register Set, and specific registers were accessed
using macros such as (port->addr + PORTPMSC).

This patch replaces the raw '__le32 __iomem *addr' pointer with a typed
'struct xhci_port_regs __iomem *port_reg' pointer. With this change,
individual registers can be accessed directly through the structure
fields:

Before:
  port->addr
  port->addr + PORTPMSC
  port->addr + PORTLI
  port->addr + PORTHLPMC

After:
  port->port_reg->portsc
  port->port_reg->portpmsc
  port->port_reg->portli
  port->port_reg->porthlpmc

This improves code readability and makes register access more intuitive
by using named struct members instead of pointer arithmetic and macros.

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20251119142417.2820519-9-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Niklas Neronin 2025-11-19 16:24:02 +02:00 committed by Greg Kroah-Hartman
parent 377a91594e
commit f2469d89a7
4 changed files with 24 additions and 30 deletions

View File

@ -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);
@ -1288,7 +1288,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]);
}
@ -1520,18 +1520,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
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) */
@ -1962,7 +1962,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]->port_reg->portsc, PORT_PLC,
PORT_PLC, 10 * 1000);
if (sret) {
xhci_warn(xhci, "port %d-%d resume PLC timeout\n",

View File

@ -2201,7 +2201,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].port_reg = &xhci->op_regs->port_regs[i];
xhci->hw_ports[i].hw_portnum = i;
init_completion(&xhci->hw_ports[i].rexit_done);

View File

@ -44,13 +44,13 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
void xhci_portsc_writel(struct xhci_port *port, u32 val)
{
trace_xhci_portsc_writel(port, val);
writel(val, port->addr);
writel(val, &port->port_reg->portsc);
}
EXPORT_SYMBOL_GPL(xhci_portsc_writel);
u32 xhci_portsc_readl(struct xhci_port *port)
{
return readl(port->addr);
return readl(&port->port_reg->portsc);
}
EXPORT_SYMBOL_GPL(xhci_portsc_readl);
@ -4649,7 +4649,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_reg;
u32 pm_val, hlpm_val, field;
unsigned int port_num;
unsigned long flags;
@ -4674,9 +4674,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_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);
@ -4705,30 +4704,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_reg->porthlmpc);
/* flush write */
readl(hlpm_addr);
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, pm_addr);
pm_val = readl(pm_addr);
writel(pm_val, &port_reg->portpmsc);
pm_val = readl(&port_reg->portpmsc);
pm_val |= PORT_HLE;
writel(pm_val, pm_addr);
writel(pm_val, &port_reg->portpmsc);
/* flush write */
readl(pm_addr);
readl(&port_reg->portpmsc);
} else {
pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
writel(pm_val, pm_addr);
writel(pm_val, &port_reg->portpmsc);
/* flush write */
readl(pm_addr);
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, pm_val,
readl_poll_timeout(&ports[port_num]->port_reg->portsc, pm_val,
(pm_val & PORT_PLS_MASK) == XDEV_U0,
100, 10000);
return 0;

View File

@ -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
@ -1470,7 +1465,7 @@ struct xhci_port_cap {
};
struct xhci_port {
__le32 __iomem *addr;
struct xhci_port_regs __iomem *port_reg;
int hw_portnum;
int hcd_portnum;
struct xhci_hub *rhub;