Convert CONFIG_USB_MAX_CONTROLLER_COUNT to Kconfig
[platform/kernel/u-boot.git] / drivers / usb / host / ehci-hcd.c
index 1edb344..f033198 100644 (file)
@@ -10,7 +10,9 @@
 #include <cpu_func.h>
 #include <dm.h>
 #include <errno.h>
+#include <log.h>
 #include <asm/byteorder.h>
+#include <asm/cache.h>
 #include <asm/unaligned.h>
 #include <usb.h>
 #include <asm/io.h>
 #include <watchdog.h>
 #include <dm/device_compat.h>
 #include <linux/compiler.h>
+#include <linux/delay.h>
 
 #include "ehci.h"
 
-#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
-#endif
-
 /*
  * EHCI spec page 20 says that the HC may take up to 16 uFrames (= 4ms) to halt.
  * Let's time out after 8 to have a little safety margin on top of that.
@@ -105,7 +104,7 @@ static struct descriptor {
        },
 };
 
-#if defined(CONFIG_EHCI_IS_TDI)
+#if defined(CONFIG_USB_EHCI_IS_TDI)
 #define ehci_is_TDI()  (1)
 #else
 #define ehci_is_TDI()  (0)
@@ -343,6 +342,28 @@ static int ehci_disable_async(struct ehci_ctrl *ctrl)
        return ret;
 }
 
+static int ehci_iaa_cycle(struct ehci_ctrl *ctrl)
+{
+       u32 cmd, status;
+       int ret;
+
+       /* Enable Interrupt on Async Advance Doorbell. */
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+       cmd |= CMD_IAAD;
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+
+       ret = handshake(&ctrl->hcor->or_usbsts, STS_IAA, STS_IAA,
+                       10 * 1000); /* 10ms timeout */
+       if (ret < 0)
+               printf("EHCI fail timeout STS_IAA set\n");
+
+       status = ehci_readl(&ctrl->hcor->or_usbsts);
+       if (status & STS_IAA)
+               ehci_writel(&ctrl->hcor->or_usbsts, STS_IAA);
+
+       return ret;
+}
+
 static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int length, struct devrequest *req)
@@ -628,6 +649,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
        flush_dcache_range((unsigned long)&ctrl->qh_list,
                ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
 
+       /* Set IAAD, poll IAA */
+       ret = ehci_iaa_cycle(ctrl);
+       if (ret)
+               goto fail;
+
        /*
         * Invalidate the memory area occupied by buffer
         * Don't try to fix the buffer alignment, if it isn't properly
@@ -1413,13 +1439,10 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev,
        debug("Exit create_int_queue\n");
        return result;
 fail3:
-       if (result->tds)
-               free(result->tds);
+       free(result->tds);
 fail2:
-       if (result->first)
-               free(result->first);
-       if (result)
-               free(result);
+       free(result->first);
+       free(result);
 fail1:
        return NULL;
 }
@@ -1762,13 +1785,13 @@ int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index)
        } else {
                ret = generic_phy_init(phy);
                if (ret) {
-                       dev_err(dev, "failed to init usb phy\n");
+                       dev_dbg(dev, "failed to init usb phy\n");
                        return ret;
                }
 
                ret = generic_phy_power_on(phy);
                if (ret) {
-                       dev_err(dev, "failed to power on usb phy\n");
+                       dev_dbg(dev, "failed to power on usb phy\n");
                        return generic_phy_exit(phy);
                }
        }
@@ -1786,13 +1809,13 @@ int ehci_shutdown_phy(struct udevice *dev, struct phy *phy)
        if (generic_phy_valid(phy)) {
                ret = generic_phy_power_off(phy);
                if (ret) {
-                       dev_err(dev, "failed to power off usb phy\n");
+                       dev_dbg(dev, "failed to power off usb phy\n");
                        return ret;
                }
 
                ret = generic_phy_exit(phy);
                if (ret) {
-                       dev_err(dev, "failed to power off usb phy\n");
+                       dev_dbg(dev, "failed to power off usb phy\n");
                        return ret;
                }
        }