USB: EHCI: use hrtimer for the I/O watchdog
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / usb / host / ehci-hub.c
index fc9e7cc6ac9b90c7914625f90d12875263ceb202..05490d387fd27c86195590f2545207172d9dac53 100644 (file)
@@ -107,7 +107,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
        ehci->owned_ports = 0;
 }
 
-static int __maybe_unused ehci_port_change(struct ehci_hcd *ehci)
+static int ehci_port_change(struct ehci_hcd *ehci)
 {
        int i = HCS_N_PORTS(ehci->hcs_params);
 
@@ -128,7 +128,7 @@ static int __maybe_unused ehci_port_change(struct ehci_hcd *ehci)
        return 0;
 }
 
-static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
+static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
                bool suspending, bool do_wakeup)
 {
        int             port;
@@ -149,10 +149,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        if (ehci->has_hostpc) {
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        temp = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
                }
@@ -185,10 +183,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        if (ehci->has_hostpc) {
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        temp = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
                }
@@ -212,8 +208,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
-       del_timer_sync(&ehci->watchdog);
-       del_timer_sync(&ehci->iaa_watchdog);
 
        spin_lock_irq (&ehci->lock);
 
@@ -231,8 +225,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        }
 
        /* stop schedules, clean any completed work */
-       if (ehci->rh_state == EHCI_RH_RUNNING)
-               ehci_quiesce (ehci);
+       ehci_quiesce(ehci);
        ehci_work(ehci);
 
        /* Unlike other USB host controller types, EHCI doesn't have
@@ -285,11 +278,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
                        u32             t3;
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        t3 = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
                        t3 = ehci_readl(ehci, hostpc_reg);
@@ -307,8 +298,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        ehci_halt (ehci);
        ehci->rh_state = EHCI_RH_SUSPENDED;
 
-       if (ehci->reclaim)
-               end_unlink_async(ehci);
+       end_unlink_async(ehci);
+       unlink_empty_async(ehci);
+       ehci_handle_intr_unlinks(ehci);
+       end_free_itds(ehci);
 
        /* allow remote wakeup */
        mask = INTR_MASK;
@@ -318,12 +311,11 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        ehci_readl(ehci, &ehci->regs->intr_enable);
 
        ehci->next_statechange = jiffies + msecs_to_jiffies(10);
+       ehci->enabled_hrtimer_events = 0;
+       ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
        spin_unlock_irq (&ehci->lock);
 
-       /* ehci_work() may have re-enabled the watchdog timer, which we do not
-        * want, and so we must delete any pending watchdog timer events.
-        */
-       del_timer_sync(&ehci->watchdog);
+       hrtimer_cancel(&ehci->hrtimer);
        return 0;
 }
 
@@ -388,10 +380,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                i = HCS_N_PORTS(ehci->hcs_params);
                while (i--) {
                        if (test_bit(i, &ehci->bus_suspended)) {
-                               u32 __iomem     *hostpc_reg;
+                               u32 __iomem     *hostpc_reg =
+                                                       &ehci->regs->hostpc[i];
 
-                               hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                               + HOSTPC0 + 4 * i);
                                temp = ehci_readl(ehci, hostpc_reg);
                                ehci_writel(ehci, temp & ~HOSTPC_PHCD,
                                                hostpc_reg);
@@ -431,23 +422,12 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                        ehci_vdbg (ehci, "resumed port %d\n", i + 1);
                }
        }
-       (void) ehci_readl(ehci, &ehci->regs->command);
-
-       /* maybe re-activate the schedule(s) */
-       temp = 0;
-       if (ehci->async->qh_next.qh)
-               temp |= CMD_ASE;
-       if (ehci->periodic_sched)
-               temp |= CMD_PSE;
-       if (temp) {
-               ehci->command |= temp;
-               ehci_writel(ehci, ehci->command, &ehci->regs->command);
-       }
 
        ehci->next_statechange = jiffies + msecs_to_jiffies(5);
 
        /* Now we can safely re-enable irqs */
        ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
+       (void) ehci_readl(ehci, &ehci->regs->intr_enable);
 
        spin_unlock_irq (&ehci->lock);
        ehci_handover_companion_ports(ehci);
@@ -667,7 +647,7 @@ static int ehci_hub_control (
        int             ports = HCS_N_PORTS (ehci->hcs_params);
        u32 __iomem     *status_reg = &ehci->regs->port_status[
                                (wIndex & 0xff) - 1];
-       u32 __iomem     *hostpc_reg = NULL;
+       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[(wIndex & 0xff) - 1];
        u32             temp, temp1, status;
        unsigned long   flags;
        int             retval = 0;
@@ -680,9 +660,6 @@ static int ehci_hub_control (
         * power, "this is the one", etc.  EHCI spec supports this.
         */
 
-       if (ehci->has_hostpc)
-               hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
-                               + HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
        spin_lock_irqsave (&ehci->lock, flags);
        switch (typeReq) {
        case ClearHubFeature:
@@ -724,7 +701,7 @@ static int ehci_hub_control (
 #ifdef CONFIG_USB_OTG
                        if ((hcd->self.otg_port == (wIndex + 1))
                            && hcd->self.b_hnp_enable) {
-                               otg_start_hnp(ehci->transceiver->otg);
+                               otg_start_hnp(hcd->phy->otg);
                                break;
                        }
 #endif
@@ -734,7 +711,7 @@ static int ehci_hub_control (
                                goto error;
 
                        /* clear phy low-power mode before resume */
-                       if (hostpc_reg) {
+                       if (ehci->has_hostpc) {
                                temp1 = ehci_readl(ehci, hostpc_reg);
                                ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
                                                hostpc_reg);
@@ -984,7 +961,7 @@ static int ehci_hub_control (
                        temp &= ~PORT_WKCONN_E;
                        temp |= PORT_WKDISC_E | PORT_WKOC_E;
                        ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
-                       if (hostpc_reg) {
+                       if (ehci->has_hostpc) {
                                spin_unlock_irqrestore(&ehci->lock, flags);
                                msleep(5);/* 5ms for HCD enter low pwr mode */
                                spin_lock_irqsave(&ehci->lock, flags);