summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayank Rana <mrana@codeaurora.org>2015-07-09 18:28:41 -0700
committerJack Pham <jackp@codeaurora.org>2016-12-13 21:22:16 -0800
commitb978a16710e7db7c9269aa6bb2172c4ea8e76b54 (patch)
treed2b44120f94a55efb1331049ef2784571c037896
parent33c3372a82653d8bc7dc563b951d3eb5efb55da7 (diff)
usb/xhci: Add support for EHSET tests for host compliance
USB 2.0 specification defines following test modes for host electrical compliance: TEST_J/K/SE0_NAK and TEST_PACKET. Hence add support for same. CRs-Fixed: 868394 Change-Id: I885ae66be2d8cca17bcc0b87b7635a71c734e4b2 Signed-off-by: Manu Gautam <mgautam@codeaurora.org> Signed-off-by: Mayank Rana <mrana@codeaurora.org>
-rw-r--r--drivers/usb/host/xhci-hub.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a7b055bc279a..b641d57fbfe1 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -885,6 +885,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 link_state = 0;
u16 wake_mask = 0;
u16 timeout = 0;
+ u16 test_mode = 0;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -958,8 +959,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
link_state = (wIndex & 0xff00) >> 3;
if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
wake_mask = wIndex & 0xff00;
- /* The MSB of wIndex is the U1/U2 timeout */
- timeout = (wIndex & 0xff00) >> 8;
+ /* The MSB of wIndex is the U1/U2 timeout OR TEST mode*/
+ test_mode = timeout = (wIndex & 0xff00) >> 8;
wIndex &= 0xff;
if (!wIndex || wIndex > max_ports)
goto error;
@@ -1133,6 +1134,27 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp |= PORT_U2_TIMEOUT(timeout);
writel(temp, port_array[wIndex] + PORTPMSC);
break;
+ case USB_PORT_FEAT_TEST:
+ slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+ wIndex + 1);
+ if (test_mode && test_mode <= 5) {
+ /* unlock to execute stop endpoint commands */
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_stop_device(xhci, slot_id, 1);
+ spin_lock_irqsave(&xhci->lock, flags);
+ xhci_halt(xhci);
+
+ temp = readl_relaxed(port_array[wIndex] +
+ PORTPMSC);
+ temp |= test_mode << 28;
+ writel_relaxed(temp, port_array[wIndex] +
+ PORTPMSC);
+ /* to make sure above write goes through */
+ mb();
+ } else {
+ goto error;
+ }
+ break;
default:
goto error;
}