]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
xhci: tegra: fix for usb2 utmi pad power saving
authorTW Chiu <twchiu@nvidia.com>
Mon, 2 Nov 2015 08:11:04 +0000 (16:11 +0800)
committermobile promotions <svcmobile_promotions@nvidia.com>
Sat, 7 Nov 2015 08:33:21 +0000 (00:33 -0800)
USB2 pad PD bits can be set to save power when device is disconnected
or suspended. When device is connected or in resume state, we need to
clear these PD bits.

During boot, there is a case that CSC bit is cleared by hub init
function. This causes PD bits set and failures in port reset and set
address.

Bug 200146188

Change-Id: Id12deb97689ef08b3e9236124c2fc4775b039c3c
Signed-off-by: TW Chiu <twchiu@nvidia.com>
Reviewed-on: http://git-master/r/826136
GVS: Gerrit_Virtual_Submit
Reviewed-by: Henry Lin <henryl@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
drivers/usb/host/xhci-tegra.c

index fedc6935d9e97890293161bc8e14d1f2b3726d94..a03ce6af66d26bfeb85563f374725a2514504cb9 100644 (file)
@@ -4084,8 +4084,8 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req,
 
        ret = xhci_hub_control(hcd, type_req, value, index, buf, length);
 
-       /* power off after port suspend */
        if ((hcd->speed == HCD_USB2) && (ret == 0)) {
+               /* power off after port suspend */
                if ((type_req == SetPortFeature) &&
                        (value == USB_PORT_FEAT_SUSPEND))
                        /* We dont suspend the PAD while HNP role swap happens
@@ -4096,6 +4096,26 @@ static int tegra_xhci_hub_control(struct usb_hcd *hcd, u16 type_req,
                            hcd->self.otg_quick_hnp))) {
                                xusb_utmi_pad_driver_power(port, false);
                        }
+
+               /* power on/off after CSC clear for connect/disconnect event */
+               if ((type_req == ClearPortFeature) &&
+                       (value == USB_PORT_FEAT_C_CONNECTION)) {
+                       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+                       u32 portsc = xhci_readl(xhci, xhci->usb2_ports[port]);
+
+                       if (portsc & PORT_CONNECT)
+                               xusb_utmi_pad_driver_power(port, true);
+                       else {
+                               /* We dont suspend the PAD while HNP
+                                * role swap happens on the OTG port
+                                */
+                               if (!((hcd->self.otg_port == (port + 1))
+                                       && (hcd->self.b_hnp_enable ||
+                                       hcd->self.otg_quick_hnp)))
+                                       xusb_utmi_pad_driver_power(
+                                                       port, false);
+                       }
+               }
        }
 
        return ret;
@@ -4116,22 +4136,6 @@ static int tegra_xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
                        /* power on for remote wakeup event */
                        if ((portsc & PORT_PLS_MASK) == XDEV_RESUME)
                                xusb_utmi_pad_driver_power(port, true);
-
-                       /* power on/off for connect/disconnect event */
-                       if (portsc & PORT_CSC) {
-                               if (portsc & PORT_CONNECT)
-                                       xusb_utmi_pad_driver_power(port, true);
-                               else {
-                                       /* We dont suspend the PAD while HNP
-                                        * role swap happens on the OTG port
-                                        */
-                                       if (!((hcd->self.otg_port == (port + 1))
-                                               && (hcd->self.b_hnp_enable ||
-                                               hcd->self.otg_quick_hnp)))
-                                               xusb_utmi_pad_driver_power(
-                                                               port, false);
-                               }
-                       }
                }
        }