aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-12-01 11:34:59 -0800
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-03-13 18:23:35 -0700
commit5308a91b9fc1a8f94b860c2589b06908a97cba7e (patch)
tree4f97e7ea4c3280b367b951ea3b1d3f07c22c1b46 /drivers/usb/host/xhci-ring.c
parentff9d78b36f76687c91c67b9f4c5c33bc888ed2f9 (diff)
downloadkernel_samsung_smdk4412-5308a91b9fc1a8f94b860c2589b06908a97cba7e.zip
kernel_samsung_smdk4412-5308a91b9fc1a8f94b860c2589b06908a97cba7e.tar.gz
kernel_samsung_smdk4412-5308a91b9fc1a8f94b860c2589b06908a97cba7e.tar.bz2
xhci: Index with a port array instead of PORTSC addresses.
In the upcoming patches, the roothub emulation code will need to return port status and port change buffers based on whether they are called with the xHCI USB 2.0 or USB 3.0 roothub. To facilitate that, make the roothub code index into an array of port addresses with wIndex, rather than calculating the address using the offset and the address of the PORTSC registers. Later we can set the port array to be the array of USB 3.0 port addresses, or the USB 2.0 port addresses, depending on the roothub passed in. Create a temporary (statically sized) port array and fill it in with both USB 3.0 and USB 2.0 port addresses. This is inefficient to do for every roothub call, but this is needed for git bisect compatibility. The temporary port array will be deleted in a subsequent patch. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 47763be..5825376 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1161,9 +1161,11 @@ static void handle_port_status(struct xhci_hcd *xhci,
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 port_id;
u32 temp, temp1;
- u32 __iomem *addr;
int max_ports;
int slot_id;
+ unsigned int faked_port_index;
+ u32 __iomem *port_array[15 + USB_MAXCHILDREN];
+ int i;
/* Port status change events always have a successful completion code */
if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) {
@@ -1179,8 +1181,16 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
}
- addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1);
- temp = xhci_readl(xhci, addr);
+ for (i = 0; i < max_ports; i++) {
+ if (i < xhci->num_usb3_ports)
+ port_array[i] = xhci->usb3_ports[i];
+ else
+ port_array[i] =
+ xhci->usb2_ports[i - xhci->num_usb3_ports];
+ }
+
+ faked_port_index = port_id;
+ temp = xhci_readl(xhci, port_array[faked_port_index]);
if (hcd->state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, "resume root hub\n");
usb_hcd_resume_root_hub(hcd);
@@ -1200,7 +1210,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | XDEV_U0;
- xhci_writel(xhci, temp, addr);
+ xhci_writel(xhci, temp, port_array[faked_port_index]);
slot_id = xhci_find_slot_id_by_port(xhci, port_id);
if (!slot_id) {
xhci_dbg(xhci, "slot_id is zero\n");
@@ -1209,10 +1219,10 @@ static void handle_port_status(struct xhci_hcd *xhci,
xhci_ring_device(xhci, slot_id);
xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
/* Clear PORT_PLC */
- temp = xhci_readl(xhci, addr);
+ temp = xhci_readl(xhci, port_array[faked_port_index]);
temp = xhci_port_state_to_neutral(temp);
temp |= PORT_PLC;
- xhci_writel(xhci, temp, addr);
+ xhci_writel(xhci, temp, port_array[faked_port_index]);
} else {
xhci_dbg(xhci, "resume HS port %d\n", port_id);
xhci->resume_done[port_id - 1] = jiffies +