usb: tegra: fix tegra ehci setup sequence
Steve Lin [Thu, 12 May 2011 23:26:40 +0000 (16:26 -0700)]
Fix tegra ehci setup sequence according to EHCI spec.
- move ehci_reset after ehci_halt
- avoid redundant ehci_reset after ehci_run. ehci_reset has a side effect
to cause phy reset for certain phy interface.
Bug 800301

Original-Change-Id: I9a798de1b6361742ce759e44d141673c0bd328b3
Reviewed-on: http://git-master/r/31432
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R6c4152855ce736f27f7972919671068e1a042b12

drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci.h

index d7318e3..13005f4 100644 (file)
@@ -277,7 +277,8 @@ static int ehci_reset (struct ehci_hcd *ehci)
 
        command |= CMD_RESET;
        dbg_cmd (ehci, "reset", command);
-       ehci_writel(ehci, command, &ehci->regs->command);
+       if (!ehci->controller_resets_phy)
+               ehci_writel(ehci, command, &ehci->regs->command);
        ehci_to_hcd(ehci)->state = HC_STATE_HALT;
        ehci->next_statechange = jiffies;
        retval = handshake (ehci, &ehci->regs->command,
index cefa7d9..5f15a6f 100644 (file)
@@ -549,12 +549,6 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
        ehci->has_hostpc = 1;
 #endif
-
-       /* switch to host mode */
-       hcd->has_tt = 1;
-       ehci_reset(ehci);
-       tegra_ehci_post_reset(tegra->phy);
-
        retval = ehci_halt(ehci);
        if (retval)
                return retval;
@@ -564,8 +558,19 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
        if (retval)
                return retval;
 
+       hcd->has_tt = 1;
        ehci->sbrn = 0x20;
 
+       ehci_reset(ehci);
+       tegra_ehci_post_reset(tegra->phy);
+
+       /*
+        * Resetting the controller has the side effect of resetting the PHY.
+        * So, never reset the controller after the calling
+        * tegra_ehci_reinit API.
+        */
+       ehci->controller_resets_phy = 1;
+
        ehci_port_power(ehci, 1);
        return retval;
 }
index d92ed5c..1b0719b 100644 (file)
@@ -140,6 +140,7 @@ struct ehci_hcd {                   /* one per controller */
        unsigned                use_dummy_qh:1; /* AMD Frame List table quirk*/
        unsigned                has_synopsys_hc_bug:1; /* Synopsys HC */
        unsigned                frame_index_bug:1; /* MosChip (AKA NetMos) */
+       unsigned                controller_resets_phy:1;
 
        /* required for usb32 quirk */
        #define OHCI_CTRL_HCFS          (3 << 6)