Use readl_poll_timeout() to poll the status of the registers. Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> --- drivers/usb/early/xhci-dbc.c | 56 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c index c0507767a8e3..77c2e8301971 100644 --- a/drivers/usb/early/xhci-dbc.c +++ b/drivers/usb/early/xhci-dbc.c @@ -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; -- 2.28.0