diff options
Diffstat (limited to 'drivers/mtd/spi-nor/cadence-quadspi.c')
| -rw-r--r-- | drivers/mtd/spi-nor/cadence-quadspi.c | 19 | 
1 files changed, 17 insertions, 2 deletions
| diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index 4b8e9183489a..5872f31eaa60 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -501,7 +501,9 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,  	void __iomem *reg_base = cqspi->iobase;  	void __iomem *ahb_base = cqspi->ahb_base;  	unsigned int remaining = n_rx; +	unsigned int mod_bytes = n_rx % 4;  	unsigned int bytes_to_read = 0; +	u8 *rxbuf_end = rxbuf + n_rx;  	int ret = 0;  	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); @@ -530,11 +532,24 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,  		}  		while (bytes_to_read != 0) { +			unsigned int word_remain = round_down(remaining, 4); +  			bytes_to_read *= cqspi->fifo_width;  			bytes_to_read = bytes_to_read > remaining ?  					remaining : bytes_to_read; -			ioread32_rep(ahb_base, rxbuf, -				     DIV_ROUND_UP(bytes_to_read, 4)); +			bytes_to_read = round_down(bytes_to_read, 4); +			/* Read 4 byte word chunks then single bytes */ +			if (bytes_to_read) { +				ioread32_rep(ahb_base, rxbuf, +					     (bytes_to_read / 4)); +			} else if (!word_remain && mod_bytes) { +				unsigned int temp = ioread32(ahb_base); + +				bytes_to_read = mod_bytes; +				memcpy(rxbuf, &temp, min((unsigned int) +							 (rxbuf_end - rxbuf), +							 bytes_to_read)); +			}  			rxbuf += bytes_to_read;  			remaining -= bytes_to_read;  			bytes_to_read = cqspi_get_rd_sram_level(cqspi); |