This looks nicer and reduces the time to transfer 40 MB at 50 MHz from 203 seconds to 87 seconds. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> --- Side note: When using while(!(readl(p->base + SPI_IF_CTRL) & IF_READ_READY)) ; return 0; instead, the time goes down to 24 seconds. I think the culprit is that get_time_ns (which is used in wait_on_timeout) handles conversion from timer values to ns. I didn't look into that (yet) but I think this could be improved by changing from: int __ret = 0; uint64_t __to_start = get_time_ns(); while (!(condition)) { if (is_timeout(__to_start, (timeout))) { __ret = -ETIMEOUT; break; } } return __ret; to something like: int __ret = 0; uint64_t __to_start_cyc = get_time_cyc(); uint64_t __timeout_cyc = ns2cyc(timeout); while (!(condition)) { if (is_timeout_cyc(__to_start_cyc, __timeout_cyc)) { __ret = -ETIMEOUT; break; } } return __ret; Here only a single conversion between cyc and ns is done and is_timeout_cyc is cheap as it doesn't need to convert. The obvious downside is that time_ns isn't updated that often. But it could still be worth the effort. Best regards Uwe drivers/spi/mvebu_spi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/spi/mvebu_spi.c b/drivers/spi/mvebu_spi.c index 68838c0ce184..f24508a7bc5d 100644 --- a/drivers/spi/mvebu_spi.c +++ b/drivers/spi/mvebu_spi.c @@ -249,13 +249,11 @@ static int mvebu_spi_setup(struct spi_device *spi) static inline int mvebu_spi_wait_for_read_ready(struct mvebu_spi *p) { - int timeout = 100; - while ((readl(p->base + SPI_IF_CTRL) & IF_READ_READY) == 0 && - timeout--) - udelay(1); - if (timeout < 0) - return -EIO; - return 0; + int ret; + + ret = wait_on_timeout(100 * USECOND, + readl(p->base + SPI_IF_CTRL) & IF_READ_READY); + return ret; } static int mvebu_spi_do_transfer(struct spi_device *spi, -- 2.10.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox