USB: EHCI: DT support for generic bus glue
[firefly-linux-kernel-4.4.55.git] / drivers / usb / host / ehci-hcd.c
index b416a3fc99594f30afbb15995191313f6c9315a6..b12b97d2ccafd628db4c0e744c1b4d3202a295cf 100644 (file)
@@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
 
 static void end_unlink_async(struct ehci_hcd *ehci);
 static void unlink_empty_async(struct ehci_hcd *ehci);
+static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
 static void ehci_work(struct ehci_hcd *ehci);
 static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
 static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
@@ -481,6 +482,9 @@ static int ehci_init(struct usb_hcd *hcd)
         * periodic_size can shrink by USBCMD update if hcc_params allows.
         */
        ehci->periodic_size = DEFAULT_I_TDPS;
+       INIT_LIST_HEAD(&ehci->async_unlink);
+       INIT_LIST_HEAD(&ehci->async_idle);
+       INIT_LIST_HEAD(&ehci->intr_unlink);
        INIT_LIST_HEAD(&ehci->intr_qh_list);
        INIT_LIST_HEAD(&ehci->cached_itd_list);
        INIT_LIST_HEAD(&ehci->cached_sitd_list);
@@ -748,17 +752,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                /* guard against (alleged) silicon errata */
                if (cmd & CMD_IAAD)
                        ehci_dbg(ehci, "IAA with IAAD still set?\n");
-               if (ehci->async_iaa) {
+               if (ehci->iaa_in_progress)
                        COUNT(ehci->stats.iaa);
-                       end_unlink_async(ehci);
-               } else
-                       ehci_dbg(ehci, "IAA with nothing unlinked?\n");
+               end_unlink_async(ehci);
        }
 
        /* remote wakeup [4.3.1] */
        if (status & STS_PCD) {
                unsigned        i = HCS_N_PORTS (ehci->hcs_params);
-               u32             ppcd = 0;
+               u32             ppcd = ~0;
 
                /* kick root hub later */
                pcd_status = status;
@@ -775,7 +777,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                        int pstatus;
 
                        /* leverage per-port change bits feature */
-                       if (ehci->has_ppcd && !(ppcd & (1 << i)))
+                       if (!(ppcd & (1 << i)))
                                continue;
                        pstatus = ehci_readl(ehci,
                                         &ehci->regs->port_status[i]);
@@ -897,17 +899,24 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        if (rc)
                goto done;
 
-       switch (usb_pipetype (urb->pipe)) {
-       // case PIPE_CONTROL:
-       // case PIPE_BULK:
-       default:
+       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+               /*
+                * We don't expedite dequeue for isochronous URBs.
+                * Just wait until they complete normally or their
+                * time slot expires.
+                */
+       } else {
                qh = (struct ehci_qh *) urb->hcpriv;
-               if (!qh)
-                       break;
+               qh->exception = 1;
                switch (qh->qh_state) {
                case QH_STATE_LINKED:
+                       if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
+                               start_unlink_intr(ehci, qh);
+                       else
+                               start_unlink_async(ehci, qh);
+                       break;
                case QH_STATE_COMPLETING:
-                       start_unlink_async(ehci, qh);
+                       qh->dequeue_during_giveback = 1;
                        break;
                case QH_STATE_UNLINK:
                case QH_STATE_UNLINK_WAIT:
@@ -918,33 +927,6 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                        qh_completions(ehci, qh);
                        break;
                }
-               break;
-
-       case PIPE_INTERRUPT:
-               qh = (struct ehci_qh *) urb->hcpriv;
-               if (!qh)
-                       break;
-               switch (qh->qh_state) {
-               case QH_STATE_LINKED:
-               case QH_STATE_COMPLETING:
-                       start_unlink_intr(ehci, qh);
-                       break;
-               case QH_STATE_IDLE:
-                       qh_completions (ehci, qh);
-                       break;
-               default:
-                       ehci_dbg (ehci, "bogus qh %p state %d\n",
-                                       qh, qh->qh_state);
-                       goto done;
-               }
-               break;
-
-       case PIPE_ISOCHRONOUS:
-               // itd or sitd ...
-
-               // wait till next completion, do it then.
-               // completion irqs can wait up to 1024 msec,
-               break;
        }
 done:
        spin_unlock_irqrestore (&ehci->lock, flags);
@@ -985,6 +967,7 @@ rescan:
                goto done;
        }
 
+       qh->exception = 1;
        if (ehci->rh_state < EHCI_RH_RUNNING)
                qh->qh_state = QH_STATE_IDLE;
        switch (qh->qh_state) {
@@ -1053,13 +1036,12 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
                usb_settoggle(qh->dev, epnum, is_out, 0);
                if (!list_empty(&qh->qtd_list)) {
                        WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-               } else if (qh->qh_state == QH_STATE_LINKED ||
-                               qh->qh_state == QH_STATE_COMPLETING) {
-
+               } else {
                        /* The toggle value in the QH can't be updated
                         * while the QH is active.  Unlink it now;
                         * re-linking will call qh_refresh().
                         */
+                       qh->exception = 1;
                        if (eptype == USB_ENDPOINT_XFER_BULK)
                                start_unlink_async(ehci, qh);
                        else
@@ -1252,11 +1234,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER                ehci_hcd_sh_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_HCD_OMAP
-#include "ehci-omap.c"
-#define        PLATFORM_DRIVER         ehci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
 #define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
@@ -1292,11 +1269,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER                ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define        PLATFORM_DRIVER         vt8500_ehci_driver
-#endif
-
 #ifdef CONFIG_PLAT_SPEAR
 #include "ehci-spear.c"
 #define PLATFORM_DRIVER                spear_ehci_hcd_driver
@@ -1346,6 +1318,7 @@ MODULE_LICENSE ("GPL");
        !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
        !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
        !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
+       !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
        !defined(PLATFORM_DRIVER) && \
        !defined(PS3_SYSTEM_BUS_DRIVER) && \
        !defined(OF_PLATFORM_DRIVER) && \