From: Heiner Kallweit Date: Thu, 27 Oct 2016 19:28:02 +0000 (+0200) Subject: spi: fsl-espi: extend and improve transfer error handling X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=db1b049fad8b12062edffade8272d604b4019eb7;p=linux-beck.git spi: fsl-espi: extend and improve transfer error handling Extend and improve transfer error handling - in case of timeout report also number of remaining rx bytes - in case of timeout return ETIMEDOUT instead of EMSGSIZE - add sanity checks after all bytes have been sent / read: - check that HW has flag SPIE_DON set - check that RX / TX FIFO are empty Signed-off-by: Heiner Kallweit Signed-off-by: Mark Brown --- diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index d5506852e63c..a9593f9691ec 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -289,13 +289,13 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ); if (ret == 0) dev_err(mpc8xxx_spi->dev, - "Transaction hanging up (left %u bytes)\n", - mpc8xxx_spi->tx_len); + "Transaction hanging up (left %u tx bytes, %u rx bytes)\n", + mpc8xxx_spi->tx_len, mpc8xxx_spi->rx_len); /* disable rx ints */ fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); - return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0; + return ret == 0 ? -ETIMEDOUT : 0; } static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) @@ -469,8 +469,20 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) if (mspi->tx_len) fsl_espi_fill_tx_fifo(mspi, events); - if (!mspi->tx_len && !mspi->rx_len) - complete(&mspi->done); + if (mspi->tx_len || mspi->rx_len) + return; + + /* we're done, but check for errors before returning */ + events = fsl_espi_read_reg(mspi, ESPI_SPIE); + + if (!(events & SPIE_DON)) + dev_err(mspi->dev, + "Transfer done but SPIE_DON isn't set!\n"); + + if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE) + dev_err(mspi->dev, "Transfer done but rx/tx fifo's aren't empty!\n"); + + complete(&mspi->done); } static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)