summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-mxic.c
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2022-01-27 12:18:04 +0300
committerMiquel Raynal <miquel.raynal@bootlin.com>2022-02-10 11:32:30 +0300
commit5fd6739e0df7e320bcac103dfb95fe75941fea17 (patch)
tree997cc9c84210837c4adf2020608c804a28b27720 /drivers/spi/spi-mxic.c
parentf9d7c7265bcff7d9a17425a8cddf702e8fe159c2 (diff)
downloadlinux-5fd6739e0df7e320bcac103dfb95fe75941fea17.tar.xz
spi: mxic: Fix the transmit path
By working with external hardware ECC engines, we figured out that Under certain circumstances, it is needed for the SPI controller to check INT_TX_EMPTY and INT_RX_NOT_EMPTY in both receive and transmit path (not only in the receive path). The delay penalty being negligible, move this code in the common path. Fixes: b942d80b0a39 ("spi: Add MXIC controller driver") Cc: stable@vger.kernel.org Suggested-by: Mason Yang <masonccyang@mxic.com.tw> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Zhengxun Li <zhengxunli@mxic.com.tw> Reviewed-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-10-miquel.raynal@bootlin.com
Diffstat (limited to 'drivers/spi/spi-mxic.c')
-rw-r--r--drivers/spi/spi-mxic.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
index 6bec0a7c77d3..22a82f5f74b5 100644
--- a/drivers/spi/spi-mxic.c
+++ b/drivers/spi/spi-mxic.c
@@ -304,25 +304,21 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf,
writel(data, mxic->regs + TXD(nbytes % 4));
+ ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
+ sts & INT_TX_EMPTY, 0, USEC_PER_SEC);
+ if (ret)
+ return ret;
+
+ ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
+ sts & INT_RX_NOT_EMPTY, 0,
+ USEC_PER_SEC);
+ if (ret)
+ return ret;
+
+ data = readl(mxic->regs + RXD);
if (rxbuf) {
- ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
- sts & INT_TX_EMPTY, 0,
- USEC_PER_SEC);
- if (ret)
- return ret;
-
- ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
- sts & INT_RX_NOT_EMPTY, 0,
- USEC_PER_SEC);
- if (ret)
- return ret;
-
- data = readl(mxic->regs + RXD);
data >>= (8 * (4 - nbytes));
memcpy(rxbuf + pos, &data, nbytes);
- WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY);
- } else {
- readl(mxic->regs + RXD);
}
WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY);