summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAdrian Alonso <aalonso@freescale.com>2015-08-06 15:46:03 -0500
committerMarek Vasut <marex@denx.de>2015-08-19 22:30:20 +0200
commitf0c89d5463d9d27679ca66b5bb86c161da15a3f7 (patch)
tree1404d787190a584a64c7ac53f37eead5f9e66725 /drivers
parent35554fc9a194802a43d50b16e92f4efc7f72bd94 (diff)
imx: usb: ehci-mx6: wait_for_bit to check reg status
Add wait_for_bit to check reg bit status and replace unbounded loops to check usb command status Signed-off-by: Adrian Alonso <aalonso@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-mx6.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 54f868420d..2666351391 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -117,12 +117,39 @@ static void usb_power_config(int index)
pll_480_ctrl_set);
}
+static int wait_for_bit(u32 *reg, const u32 mask, bool set)
+{
+ u32 val;
+ const unsigned int timeout = 10000;
+ unsigned long start = get_timer(0);
+
+ while(1) {
+ val = readl(reg);
+ if (!set)
+ val = ~val;
+
+ if ((val & mask) == mask)
+ return 0;
+
+ if (get_timer(start) > timeout)
+ break;
+
+ udelay(1);
+ }
+
+ debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
+ __func__, reg, mask, set);
+
+ return -ETIMEDOUT;
+}
+
/* Return 0 : host node, <>0 : device mode */
static int usb_phy_enable(int index, struct usb_ehci *ehci)
{
void __iomem *phy_reg;
void __iomem *phy_ctrl;
void __iomem *usb_cmd;
+ int ret;
if (index >= ARRAY_SIZE(phy_bases))
return 0;
@@ -133,12 +160,14 @@ static int usb_phy_enable(int index, struct usb_ehci *ehci)
/* Stop then Reset */
clrbits_le32(usb_cmd, UCMD_RUN_STOP);
- while (readl(usb_cmd) & UCMD_RUN_STOP)
- ;
+ ret = wait_for_bit(usb_cmd, UCMD_RUN_STOP, 0);
+ if (ret)
+ return ret;
setbits_le32(usb_cmd, UCMD_RESET);
- while (readl(usb_cmd) & UCMD_RESET)
- ;
+ ret = wait_for_bit(usb_cmd, UCMD_RESET, 0);
+ if (ret)
+ return ret;
/* Reset USBPHY module */
setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST);