[PATCH 1/4] spi: spi-mem: Add a no_cs_assertion capability
From: Miquel Raynal
Date: Thu Mar 26 2026 - 12:55:16 EST
Some controllers are 'smart', and that's a problem.
For instance, the Cadence quadspi controller is capable of deasserting
the CS automatically whenever a too long period of time without any data
to transfer elapses.
This 'feature' combined with a loaded interconnect with arbitration, a
"long" transfer may be split into smaller DMA transfers. In this case
the controller may allow itself to deassert the CS between chunks.
Deasserting the CS stops any ongoing continuous read. Reasserting it
later to continue the reading will only result in the host getting
garbage.
In this case, the host controller driver has no control over the CS
state, so we cannot reliably enable continuous reads. Flag this
limitation through a spi-mem controller capability.
The inversion in the flag name (starting with 'no_') is voluntary, in
order to avoid the need to set this flag in all controller drivers. Only
the broken controllers shall set this bit, the default being that the
controller masters its CS fully.
Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
I am open to suggestions regarding the naming of this flag.
---
include/linux/spi/spi-mem.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index bd2a73d46980..de153719a08e 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -373,7 +373,10 @@ struct spi_controller_mem_ops {
* @swap16: Supports swapping bytes on a 16 bit boundary when configured in
* Octal DTR
* @per_op_freq: Supports per operation frequency switching
- * @secondary_op_tmpl: Supports leveraging a secondary memory operation template
+ * @no_cs_assertion: The controller may automatically deassert the CS if there
+ * is a pause in the transfer (eg. internal bus contention or
+ * DMA arbitration on an interconnect). Features such as NAND
+ * continuous reads shall not be leveraged.
*/
struct spi_controller_mem_caps {
bool dtr;
@@ -381,6 +384,7 @@ struct spi_controller_mem_caps {
bool swap16;
bool per_op_freq;
bool secondary_op_tmpl;
+ bool no_cs_assertion;
};
#define spi_mem_controller_is_capable(ctlr, cap) \
--
2.51.1