From: Nobuteru Hayashi Date: Fri, 18 Mar 2016 11:35:21 +0000 (+0000) Subject: spi/fsl-espi: Don't spin forever on SPIE_RXCNT X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=a12ddd60ed0a88c3bb83a8d4c07762e41620bf8c;p=deliverable%2Flinux.git spi/fsl-espi: Don't spin forever on SPIE_RXCNT Infinite loop on SPIE_RXCNT occurred. while (SPIE_RXCNT(events) < min(4, mspi->len)) { cpu_relax(); events = mpc8xxx_spi_read_reg(®_base->event); } We met a soft lockup at fsl_espi_cpu_irq() because of this. Fix it by using spin_event_timeout() so that fsl_espi_cpu_irq() can break loop with timeouts dmesg. Signed-off-by: Nobuteru Hayashi Signed-off-by: Mark Brown --- diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 7cb0c1921495..5d7fb81240cd 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -539,11 +539,18 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) if (events & SPIE_NE) { u32 rx_data, tmp; u8 rx_data_8; + int ret; /* Spin until RX is done */ - while (SPIE_RXCNT(events) < min(4, mspi->len)) { - cpu_relax(); - events = mpc8xxx_spi_read_reg(®_base->event); + if (SPIE_RXCNT(events) < min(4, mspi->len)) { + ret = spin_event_timeout( + !(SPIE_RXCNT(events = + mpc8xxx_spi_read_reg(®_base->event)) < + min(4, mspi->len)), + 10000, 0); /* 10 msec */ + if (!ret) + dev_err(mspi->dev, + "tired waiting for SPIE_RXCNT\n"); } if (mspi->len >= 4) {