summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-mem.c17
-rw-r--r--include/linux/spi/spi-mem.h5
2 files changed, 22 insertions, 0 deletions
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index e2eaa1ba4ff6..f64eda9bbd9f 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -713,6 +713,23 @@ spi_mem_dirmap_create(struct spi_mem *mem,
if (info->primary_op_tmpl.data.dir == SPI_MEM_NO_DATA)
return ERR_PTR(-EINVAL);
+ /* Apply similar constraints to the secondary template */
+ if (info->secondary_op_tmpl.cmd.opcode) {
+ if (!info->secondary_op_tmpl.addr.nbytes ||
+ info->secondary_op_tmpl.addr.nbytes > 8)
+ return ERR_PTR(-EINVAL);
+
+ if (info->secondary_op_tmpl.data.dir == SPI_MEM_NO_DATA)
+ return ERR_PTR(-EINVAL);
+
+ if (!spi_mem_supports_op(mem, &info->secondary_op_tmpl))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if (ctlr->mem_ops && ctlr->mem_ops->dirmap_create &&
+ !spi_mem_controller_is_capable(ctlr, secondary_op_tmpl))
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
desc = kzalloc_obj(*desc);
if (!desc)
return ERR_PTR(-ENOMEM);
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index 9a96ddace3eb..2012a3b2ef91 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -227,6 +227,8 @@ struct spi_mem_op {
* struct spi_mem_dirmap_info - Direct mapping information
* @op_tmpl: operation template that should be used by the direct mapping when
* the memory device is accessed
+ * @secondary_op_tmpl: secondary template, may be used as an alternative to the
+ * primary template (decided by the upper layer)
* @offset: absolute offset this direct mapping is pointing to
* @length: length in byte of this direct mapping
*
@@ -239,6 +241,7 @@ struct spi_mem_op {
struct spi_mem_dirmap_info {
struct spi_mem_op *op_tmpl;
struct spi_mem_op primary_op_tmpl;
+ struct spi_mem_op secondary_op_tmpl;
u64 offset;
u64 length;
};
@@ -382,12 +385,14 @@ 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
*/
struct spi_controller_mem_caps {
bool dtr;
bool ecc;
bool swap16;
bool per_op_freq;
+ bool secondary_op_tmpl;
};
#define spi_mem_controller_is_capable(ctlr, cap) \