usb: host: tegra: hotplug delay reduction
Suresh Mangipudi [Mon, 23 May 2011 11:53:59 +0000 (16:53 +0530)]
PortConnectionDetect to be cleared if the usbphy clock interrupt is set.
The USB plugin detection is done appropriately without missing
cableconnect event.

Bug 825920

(cherry picked from commit b5d5cd3e4e7af0915d2013f578f285244d7e5acd)

Original-Change-Id: Ie6b7b83b0bf056ec8b3ae6310b2b610b714f9109
Reviewed-on: http://git-master/r/34839
Reviewed-by: Suresh Mangipudi <smangipudi@nvidia.com>
Tested-by: Suresh Mangipudi <smangipudi@nvidia.com>
Reviewed-by: Rakesh Bodla <rbodla@nvidia.com>
Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com>

Rebase-Id: Rdaf3a4842403c583c4c8cd8676c5b0f1e529a45e

drivers/usb/host/ehci-tegra.c

index 6bf5731..46489cf 100644 (file)
@@ -31,6 +31,7 @@
 #define TEGRA_USB_PHY_CLK_VALID                        (1 << 7)
 #define TEGRA_USB_SRT                          (1 << 25)
 #define TEGRA_USB_PHY_CLK_VALID_INT_ENB        (1 << 9)
+#define TEGRA_USB_PHY_CLK_VALID_INT_STS        (1 << 8)
 
 #define TEGRA_USB_PORTSC1_OFFSET               0x184
 #define TEGRA_USB_PORTSC1_WKCN                 (1 << 20)
@@ -145,19 +146,27 @@ static int tegra_ehci_internal_port_reset(
 static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd)
 {
        struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+       struct ehci_regs __iomem *hw = ehci->regs;
        u32 val;
 
-       spin_lock (&ehci->lock);
+       spin_lock(&ehci->lock);
        val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET);
-       val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB;
-       writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET));
-
-       val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET);
-       val &= ~TEGRA_USB_PORTSC1_WKCN;
-       writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET));
-
-       spin_unlock (&ehci->lock);
-
+       if ((val  & TEGRA_USB_PHY_CLK_VALID_INT_STS)) {
+               val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB |
+                               TEGRA_USB_PHY_CLK_VALID_INT_STS;
+               writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET));
+
+               val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET);
+               val &= ~TEGRA_USB_PORTSC1_WKCN;
+               writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET));
+
+               val = readl(&hw->status);
+               if (!(val  & STS_PCD)) {
+                       spin_unlock(&ehci->lock);
+                       return 0;
+               }
+       }
+       spin_unlock(&ehci->lock);
        return ehci_irq(hcd);
 }