From 0bee4412b53ba183ee9be9ddb54b31bf0eae1bf1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 4 Nov 2011 13:26:44 -0700 Subject: [PATCH] 3.1 patches --- queue-3.1/series | 2 + ...ci-clear-plc-for-usb2-root-hub-ports.patch | 39 +++++++++ queue-3.1/xhci-test-and-clear-rwc-bit.patch | 85 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 queue-3.1/xhci-clear-plc-for-usb2-root-hub-ports.patch create mode 100644 queue-3.1/xhci-test-and-clear-rwc-bit.patch diff --git a/queue-3.1/series b/queue-3.1/series index 9da0179f750..af57bc25aca 100644 --- a/queue-3.1/series +++ b/queue-3.1/series @@ -175,3 +175,5 @@ ext4-let-ext4_page_mkwrite-stop-started-handle-in-failure.patch ext4-fix-race-in-xattr-block-allocation-path.patch usb_storage-don-t-freeze-in-usb-stor-scan.patch xhci-if-no-endpoints-changed-don-t-issue-bw-command.patch +xhci-test-and-clear-rwc-bit.patch +xhci-clear-plc-for-usb2-root-hub-ports.patch diff --git a/queue-3.1/xhci-clear-plc-for-usb2-root-hub-ports.patch b/queue-3.1/xhci-clear-plc-for-usb2-root-hub-ports.patch new file mode 100644 index 00000000000..68299cd3804 --- /dev/null +++ b/queue-3.1/xhci-clear-plc-for-usb2-root-hub-ports.patch @@ -0,0 +1,39 @@ +From 6fd4562178508a0949c9fdecd8558d8b10d671bd Mon Sep 17 00:00:00 2001 +From: Andiry Xu +Date: Fri, 23 Sep 2011 14:19:50 -0700 +Subject: xHCI: Clear PLC for USB2 root hub ports + +From: Andiry Xu + +commit 6fd4562178508a0949c9fdecd8558d8b10d671bd upstream. + +When the link state changes, xHC will report a port status change event +and set the PORT_PLC bit, for both USB3 and USB2 root hub ports. + +The PLC will be cleared by usbcore for USB3 root hub ports, but not for +USB2 ports, because they do not report USB_PORT_STAT_C_LINK_STATE in +wPortChange. + +Clear it for USB2 root hub ports in handle_port_status(). + +Signed-off-by: Andiry Xu +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1356,6 +1356,10 @@ static void handle_port_status(struct xh + } + } + ++ if (hcd->speed != HCD_USB3) ++ xhci_test_and_clear_bit(xhci, port_array, faked_port_index, ++ PORT_PLC); ++ + cleanup: + /* Update event ring dequeue pointer before dropping the lock */ + inc_deq(xhci, xhci->event_ring, true); diff --git a/queue-3.1/xhci-test-and-clear-rwc-bit.patch b/queue-3.1/xhci-test-and-clear-rwc-bit.patch new file mode 100644 index 00000000000..b4c0c5b8b16 --- /dev/null +++ b/queue-3.1/xhci-test-and-clear-rwc-bit.patch @@ -0,0 +1,85 @@ +From d2f52c9e585bbb1a3c164e02b8dcd0d996c67353 Mon Sep 17 00:00:00 2001 +From: Andiry Xu +Date: Fri, 23 Sep 2011 14:19:49 -0700 +Subject: xHCI: test and clear RWC bit + +From: Andiry Xu + +commit d2f52c9e585bbb1a3c164e02b8dcd0d996c67353 upstream. + +Introduce xhci_test_and_clear_bit() to clear RWC bit in PORTSC register. + +Signed-off-by: Andiry Xu +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 22 ++++++++++++++++------ + drivers/usb/host/xhci-ring.c | 6 ++---- + drivers/usb/host/xhci.h | 2 ++ + 3 files changed, 20 insertions(+), 10 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -392,6 +392,20 @@ static int xhci_get_ports(struct usb_hcd + return max_ports; + } + ++/* Test and clear port RWC bit */ ++void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, ++ int port_id, u32 port_bit) ++{ ++ u32 temp; ++ ++ temp = xhci_readl(xhci, port_array[port_id]); ++ if (temp & port_bit) { ++ temp = xhci_port_state_to_neutral(temp); ++ temp |= port_bit; ++ xhci_writel(xhci, temp, port_array[port_id]); ++ } ++} ++ + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength) + { +@@ -938,12 +952,8 @@ int xhci_bus_resume(struct usb_hcd *hcd) + spin_lock_irqsave(&xhci->lock, flags); + + /* Clear PLC */ +- temp = xhci_readl(xhci, port_array[port_index]); +- if (temp & PORT_PLC) { +- temp = xhci_port_state_to_neutral(temp); +- temp |= PORT_PLC; +- xhci_writel(xhci, temp, port_array[port_index]); +- } ++ xhci_test_and_clear_bit(xhci, port_array, port_index, ++ PORT_PLC); + + slot_id = xhci_find_slot_id_by_port(hcd, + xhci, port_index + 1); +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1344,10 +1344,8 @@ static void handle_port_status(struct xh + xhci_ring_device(xhci, slot_id); + xhci_dbg(xhci, "resume SS port %d finished\n", port_id); + /* Clear PORT_PLC */ +- temp = xhci_readl(xhci, port_array[faked_port_index]); +- temp = xhci_port_state_to_neutral(temp); +- temp |= PORT_PLC; +- xhci_writel(xhci, temp, port_array[faked_port_index]); ++ xhci_test_and_clear_bit(xhci, port_array, ++ faked_port_index, PORT_PLC); + } else { + xhci_dbg(xhci, "resume HS port %d\n", port_id); + bus_state->resume_done[faked_port_index] = jiffies + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1573,6 +1573,8 @@ void xhci_ring_ep_doorbell(struct xhci_h + unsigned int ep_index, unsigned int stream_id); + + /* xHCI roothub code */ ++void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, ++ int port_id, u32 port_bit); + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, + char *buf, u16 wLength); + int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); -- 2.47.3