summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Roese <[email protected]>2015-01-09 14:39:22 +0100
committerJagannadha Sutradharudu Teki <[email protected]>2015-04-22 16:49:51 +0530
commited62756dcf5544e277d87c461a84c6274f42b765 (patch)
tree9695aa03ae956788fdfa983c9f57312528c238c2
parentd15e74f16cc521da0e08060cda2c87307bd4363f (diff)
cmd_sf: Fix problem with "sf update" and unaligned length
On SoCFPGA, using "sf update" with an non-4byte aligned length leads to a hangup (and reboot via watchdog). This is because of the unaligned access in the cadence QSPI driver which is hard to prevent since the data is written into a 4-byte wide FIFO. This patch fixes this problem by changing the behavior of the last sector write (not sector aligned). The new code is even simpler and copies the source data into the temp buffer and now uses the temp buffer to write the complete sector. So only one SPI sector write is used now instead of 2 in the old version. Signed-off-by: Stefan Roese <[email protected]> Cc: Gerlando Falauto <[email protected]> Cc: Valentin Longchamp <[email protected]> Cc: Holger Brunck <[email protected]> Acked-by: Gerlando Falauto <[email protected]> Reviewed-by: Jagannadha Sutradharudu Teki <[email protected]>
-rw-r--r--common/cmd_sf.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 6aabf39302c..342021df97e 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -164,6 +164,8 @@ static int do_spi_flash_probe(int argc, char * const argv[])
static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
size_t len, const char *buf, char *cmp_buf, size_t *skipped)
{
+ char *ptr = (char *)buf;
+
debug("offset=%#x, sector_size=%#x, len=%#zx\n",
offset, flash->sector_size, len);
/* Read the entire sector so to allow for rewriting */
@@ -179,16 +181,14 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
/* Erase the entire sector */
if (spi_flash_erase(flash, offset, flash->sector_size))
return "erase";
- /* Write the initial part of the block from the source */
- if (spi_flash_write(flash, offset, len, buf))
- return "write";
- /* If it's a partial sector, rewrite the existing part */
+ /* If it's a partial sector, copy the data into the temp-buffer */
if (len != flash->sector_size) {
- /* Rewrite the original data to the end of the sector */
- if (spi_flash_write(flash, offset + len,
- flash->sector_size - len, &cmp_buf[len]))
- return "write";
+ memcpy(cmp_buf, buf, len);
+ ptr = cmp_buf;
}
+ /* Write one complete sector */
+ if (spi_flash_write(flash, offset, flash->sector_size, ptr))
+ return "write";
return NULL;
}