drivers/spi/spi_flash: honor spi controller fifo size for reads
The spi_flash_cmd_read_fast() and spi_flash_cmd_read_slow() were just passing full size buffers to the spi controller ops. However, the code wasn't honoring what the spi controller can actually perform. This would cause failures to read on controllers when large requests were sent in. Fix this by introducing a spi_flash_cmd_read_array_wrapped() function that calls spi_flash_cmd_read_array() in a loop once the maximum transfer size is calculated based on the spi controller's settings. BUG=b:65485690 Change-Id: I442d6e77a93fda411cb289b606189e490a4e464e Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/23444 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Justin TerAvest <teravest@chromium.org>
This commit is contained in:
parent
e98722856e
commit
3a649eec28
|
@ -113,6 +113,34 @@ static int spi_flash_cmd_read_array(const struct spi_slave *spi, u8 *cmd,
|
|||
return spi_flash_cmd_read(spi, cmd, cmd_len, data, len);
|
||||
}
|
||||
|
||||
/* Perform the read operation honoring spi controller fifo size, reissuing
|
||||
* the read command until the full request completed. */
|
||||
static int spi_flash_cmd_read_array_wrapped(const struct spi_slave *spi,
|
||||
u8 *cmd, size_t cmd_len, u32 offset,
|
||||
size_t len, void *buf)
|
||||
{
|
||||
int ret;
|
||||
size_t xfer_len;
|
||||
uint8_t *data = buf;
|
||||
|
||||
while (len) {
|
||||
xfer_len = spi_crop_chunk(spi, cmd_len, len);
|
||||
|
||||
/* Perform the read. */
|
||||
ret = spi_flash_cmd_read_array(spi, cmd, cmd_len,
|
||||
offset, xfer_len, data);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
offset += xfer_len;
|
||||
data += xfer_len;
|
||||
len -= xfer_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
|
||||
size_t len, void *data)
|
||||
{
|
||||
|
@ -121,7 +149,7 @@ int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
|
|||
cmd[0] = CMD_READ_ARRAY_FAST;
|
||||
cmd[4] = 0x00;
|
||||
|
||||
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
|
||||
return spi_flash_cmd_read_array_wrapped(&flash->spi, cmd, sizeof(cmd),
|
||||
offset, len, data);
|
||||
}
|
||||
|
||||
|
@ -131,7 +159,7 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset,
|
|||
u8 cmd[4];
|
||||
|
||||
cmd[0] = CMD_READ_ARRAY_SLOW;
|
||||
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
|
||||
return spi_flash_cmd_read_array_wrapped(&flash->spi, cmd, sizeof(cmd),
|
||||
offset, len, data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue