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

spi: cadence-quadspi: fix incorrect supports_op() return value

Since the conversion to spi-mem, the driver advertised support for
various operations that cqspi_set_protocol() was never expected to handle
correctly - in particuar all non-DTR operations with command or address
buswidth > 1. For DTR, all operations except for 8-8-8 would fail, as
cqspi_set_protocol() returns -EINVAL.

In non-DTR mode, this resulted in data corruption for SPI-NOR flashes that
support such operations. As a minimal fix that can be backported to stable
kernels, simply disallow the unsupported operations again to avoid this
issue.

Fixes: a314f6367787 ("mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework")
Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Link: https://lore.kernel.org/r/20220406132832.199777-1-matthias.schiffer@ew.tq-group.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Matthias Schiffer and committed by
Mark Brown
f1d388f2 299d8b74

+17 -2
+17 -2
drivers/spi/spi-cadence-quadspi.c
··· 1415 1415 all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr && 1416 1416 !op->data.dtr; 1417 1417 1418 - /* Mixed DTR modes not supported. */ 1419 - if (!(all_true || all_false)) 1418 + if (all_true) { 1419 + /* Right now we only support 8-8-8 DTR mode. */ 1420 + if (op->cmd.nbytes && op->cmd.buswidth != 8) 1421 + return false; 1422 + if (op->addr.nbytes && op->addr.buswidth != 8) 1423 + return false; 1424 + if (op->data.nbytes && op->data.buswidth != 8) 1425 + return false; 1426 + } else if (all_false) { 1427 + /* Only 1-1-X ops are supported without DTR */ 1428 + if (op->cmd.nbytes && op->cmd.buswidth > 1) 1429 + return false; 1430 + if (op->addr.nbytes && op->addr.buswidth > 1) 1431 + return false; 1432 + } else { 1433 + /* Mixed DTR modes are not supported. */ 1420 1434 return false; 1435 + } 1421 1436 1422 1437 return spi_mem_default_supports_op(mem, op); 1423 1438 }