In case of a non-aligned length of flash data, the remaining bytes are
written to the ahbbase address with byte accesses. This sometimes
causes AHB bus errors, resulting in a kernel crash while booting
Linux. To avoid this, write a 4-byte aligned word to the ahbbase
address.
Use a temporary variable with 0xffffffff data and overwrite it with
the unaligned bytes before writing it to ahbbase.
The value 0xffffffff is chosen as this is flash memory, in the worst
case 0xff is written to a location, which does not affect any bits.
Fixes: 26da6353e171 ("mtd: cqspi: Simplify indirect write code")
Signed-off-by: Ashok Reddy Soma <[email protected]>
Signed-off-by: Tejas Bhumkar <[email protected]>
Signed-off-by: Venkatesh Yadav Abbarapu <[email protected]>
Signed-off-by: Padmarao Begari <[email protected]>
---
drivers/spi/cadence_qspi_apb.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index f62238647e3..2cf8cb0d0f0 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -934,10 +934,14 @@ cadence_qspi_apb_indirect_write_execute(struct
cadence_spi_priv *priv,
while (remaining > 0) {
write_bytes = remaining > page_size ? page_size : remaining;
writesl(priv->ahbbase, bb_txbuf, write_bytes >> 2);
- if (write_bytes % 4)
- writesb(priv->ahbbase,
- bb_txbuf + rounddown(write_bytes, 4),
- write_bytes % 4);
+ if (write_bytes % 4) {
+ /* Pad with 0xff, which leaves the flash bits unchanged
*/
+ u32 temp = U32_MAX;
+
+ memcpy(&temp, bb_txbuf + rounddown(write_bytes, 4),
+ write_bytes % 4);
+ writel(temp, priv->ahbbase);
+ }
ret = readl_poll_timeout(priv->regbase + CQSPI_REG_IRQSTATUS,
cr, cr & CQSPI_REG_IRQ_IND_COMP,
--
2.34.1