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
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-08 15:22:53 +0300
commit7d94d25c7972195a5cbd89baeb8223dd6845ac8a (patch)
tree9752b1fb155bbde5f526f4275ff7ce9b1ef4ec4e /drivers/spi/spi-mxic.c
parent48254561bd04992d4e2a1b5b35f314d908f83fe0 (diff)
downloadlinux-7d94d25c7972195a5cbd89baeb8223dd6845ac8a.tar.xz
spi: mxic: Fix the transmit path
commit 5fd6739e0df7e320bcac103dfb95fe75941fea17 upstream. 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 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 45889947afed..03fce4493aa7 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);