@@ -14,6 +14,7 @@
#include <linux/pci_ids.h>
#include <linux/memblock.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <asm/pci-direct.h>
#include <asm/fixmap.h>
#include <linux/bcd.h>
@@ -131,38 +132,23 @@ static u32 __init xdbc_find_dbgp(int xdbc_num, u32 *b, u32 *d, u32 *f)
return -1;
}
-static int handshake(void __iomem *ptr, u32 mask, u32 done, int wait, int delay)
-{
- u32 result;
-
- do {
- result = readl(ptr);
- result &= mask;
- if (result == done)
- return 0;
- udelay(delay);
- wait -= delay;
- } while (wait > 0);
-
- return -ETIMEDOUT;
-}
-
static void __init xdbc_bios_handoff(void)
{
int offset, timeout;
u32 val;
offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_LEGACY);
- val = readl(xdbc.xhci_base + offset);
- if (val & XHCI_HC_BIOS_OWNED) {
+ val = readl(xdbc.xhci_base + offset);
+ if (val & XHCI_HC_BIOS_OWNED)
writel(val | XHCI_HC_OS_OWNED, xdbc.xhci_base + offset);
- timeout = handshake(xdbc.xhci_base + offset, XHCI_HC_BIOS_OWNED, 0, 5000, 10);
- if (timeout) {
- pr_notice("failed to hand over xHCI control from BIOS\n");
- writel(val & ~XHCI_HC_BIOS_OWNED, xdbc.xhci_base + offset);
- }
+ timeout = readl_poll_timeout_atomic(xdbc.xhci_base + offset, val,
+ !(val & XHCI_HC_BIOS_OWNED),
+ 10, 5000);
+ if (timeout) {
+ pr_notice("failed to hand over xHCI control from BIOS\n");
+ writel(val & ~XHCI_HC_BIOS_OWNED, xdbc.xhci_base + offset);
}
/* Disable BIOS SMIs and clear all SMI events: */
@@ -421,7 +407,9 @@ static int xdbc_start(void)
ctrl = readl(&xdbc.xdbc_reg->control);
writel(ctrl | CTRL_DBC_ENABLE | CTRL_PORT_ENABLE, &xdbc.xdbc_reg->control);
- ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, CTRL_DBC_ENABLE, 100000, 100);
+ ret = readl_poll_timeout_atomic(&xdbc.xdbc_reg->control, ctrl,
+ (ctrl & CTRL_DBC_ENABLE) == CTRL_DBC_ENABLE,
+ 100, 100000);
if (ret) {
xdbc_trace("failed to initialize hardware\n");
return ret;
@@ -432,14 +420,18 @@ static int xdbc_start(void)
xdbc_reset_debug_port();
/* Wait for port connection: */
- ret = handshake(&xdbc.xdbc_reg->portsc, PORTSC_CONN_STATUS, PORTSC_CONN_STATUS, 5000000, 100);
+ ret = readl_poll_timeout_atomic(&xdbc.xdbc_reg->portsc, status,
+ (status & PORTSC_CONN_STATUS) == PORTSC_CONN_STATUS,
+ 100, 5000000);
if (ret) {
xdbc_trace("waiting for connection timed out\n");
return ret;
}
/* Wait for debug device to be configured: */
- ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_RUN, CTRL_DBC_RUN, 5000000, 100);
+ ret = readl_poll_timeout_atomic(&xdbc.xdbc_reg->control, status,
+ (status & CTRL_DBC_RUN) == CTRL_DBC_RUN,
+ 100, 5000000);
if (ret) {
xdbc_trace("waiting for device configuration timed out\n");
return ret;
@@ -523,11 +515,14 @@ static int xdbc_bulk_transfer(void *data, int size, bool read)
static int xdbc_handle_external_reset(void)
{
- int ret = 0;
+ u32 result;
+ int ret;
xdbc.flags = 0;
writel(0, &xdbc.xdbc_reg->control);
- ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, 0, 100000, 10);
+ ret = readl_poll_timeout_atomic(&xdbc.xdbc_reg->control, result,
+ !(result & CTRL_DBC_ENABLE),
+ 10, 100000);
if (ret)
goto reset_out;
@@ -552,10 +547,13 @@ static int xdbc_handle_external_reset(void)
static int __init xdbc_early_setup(void)
{
+ u32 result;
int ret;
writel(0, &xdbc.xdbc_reg->control);
- ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, 0, 100000, 100);
+ ret = readl_poll_timeout_atomic(&xdbc.xdbc_reg->control, result,
+ !(result & CTRL_DBC_ENABLE),
+ 100, 100000);
if (ret)
return ret;
Use readl_poll_timeout() to poll the status of the registers. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- v2: no change drivers/usb/early/xhci-dbc.c | 56 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 29 deletions(-)