Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: spi: ti-qspi: wait for busy bit clear before data write/read

Data corruption is seen while reading/writing large data from/to qspi
device because the data register is over written or read before data
is ready which is denoted by busy bit in status register. SO adding
a busy bit check before writing/reading data to/from qspi device.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Mugunthan V N and committed by
Mark Brown
00611047 66886337

+22
+22
drivers/spi/spi-ti-qspi.c
··· 101 101 #define QSPI_FLEN(n) ((n - 1) << 0) 102 102 103 103 /* STATUS REGISTER */ 104 + #define BUSY 0x01 104 105 #define WC 0x02 105 106 106 107 /* INTERRUPT REGISTER */ ··· 200 199 ti_qspi_write(qspi, ctx_reg->clkctrl, QSPI_SPI_CLOCK_CNTRL_REG); 201 200 } 202 201 202 + static inline u32 qspi_is_busy(struct ti_qspi *qspi) 203 + { 204 + u32 stat; 205 + unsigned long timeout = jiffies + QSPI_COMPLETION_TIMEOUT; 206 + 207 + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); 208 + while ((stat & BUSY) && time_after(timeout, jiffies)) { 209 + cpu_relax(); 210 + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); 211 + } 212 + 213 + WARN(stat & BUSY, "qspi busy\n"); 214 + return stat & BUSY; 215 + } 216 + 203 217 static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) 204 218 { 205 219 int wlen, count; ··· 227 211 wlen = t->bits_per_word >> 3; /* in bytes */ 228 212 229 213 while (count) { 214 + if (qspi_is_busy(qspi)) 215 + return -EBUSY; 216 + 230 217 switch (wlen) { 231 218 case 1: 232 219 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", ··· 285 266 286 267 while (count) { 287 268 dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); 269 + if (qspi_is_busy(qspi)) 270 + return -EBUSY; 271 + 288 272 ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); 289 273 if (!wait_for_completion_timeout(&qspi->transfer_complete, 290 274 QSPI_COMPLETION_TIMEOUT)) {