From: Miquel Raynal <[email protected]> As of now, we only use a single operation template when creating SPI memory direct mappings. With the idea to extend this possibility to 2, rename the template to reflect that we are currently setting the "primary" operation, and create a pointer in the same structure to point to it.
>From a user point of view, the op_tmpl name remains but becomes a pointer, leading to minor changes in both the SPI NAND and SPI NOR cores. There is no functional change. Acked-by: Mark Brown <[email protected]> Signed-off-by: Miquel Raynal <[email protected]> [Linux commit: 39d0ea33123ffe0214217b529830ad91574c8757] Signed-off-by: Mikhail Kshevetskiy <[email protected]> --- drivers/mtd/nand/spi/core.c | 4 ++-- drivers/mtd/spi/sf_probe.c | 22 ++++++++++++---------- drivers/mtd/spi/spi-nor-core.c | 20 ++++++++++++-------- drivers/spi/airoha_snfi_spi.c | 10 +++++----- drivers/spi/spi-aspeed-smc.c | 8 ++++---- drivers/spi/spi-mem.c | 15 ++++++++------- include/spi-mem.h | 3 ++- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 14af4264612..5c54e726c4f 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1174,14 +1174,14 @@ static int spinand_create_dirmap(struct spinand_device *spinand, info.offset = plane << fls(nand->memorg.pagesize); info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); - info.op_tmpl = *spinand->op_templates.update_cache; + info.primary_op_tmpl = *spinand->op_templates.update_cache; desc = spi_mem_dirmap_create(spinand->slave, &info); if (IS_ERR(desc)) return PTR_ERR(desc); spinand->dirmaps[plane].wdesc = desc; - info.op_tmpl = *spinand->op_templates.read_cache; + info.primary_op_tmpl = *spinand->op_templates.read_cache; desc = spinand_create_rdesc(spinand, &info); if (IS_ERR(desc)) { spi_mem_dirmap_destroy(spinand->dirmaps[plane].wdesc); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index dee03662d45..0d01753b884 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -21,14 +21,15 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor) { struct spi_mem_dirmap_info info = { - .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), - SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), - SPI_MEM_OP_DUMMY(nor->read_dummy, 0), - SPI_MEM_OP_DATA_IN(0, NULL, 0)), + .op_tmpl = &info.primary_op_tmpl, + .primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_DUMMY(nor->read_dummy, 0), + SPI_MEM_OP_DATA_IN(0, NULL, 0)), .offset = 0, .length = nor->mtd.size, }; - struct spi_mem_op *op = &info.op_tmpl; + struct spi_mem_op *op = info.op_tmpl; /* get transfer protocols. */ spi_nor_setup_op(nor, op, nor->read_proto); @@ -49,14 +50,15 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor) static int spi_nor_create_write_dirmap(struct spi_nor *nor) { struct spi_mem_dirmap_info info = { - .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0), - SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(0, NULL, 0)), + .op_tmpl = &info.primary_op_tmpl, + .primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(0, NULL, 0)), .offset = 0, .length = nor->mtd.size, }; - struct spi_mem_op *op = &info.op_tmpl; + struct spi_mem_op *op = info.op_tmpl; /* get transfer protocols. */ spi_nor_setup_op(nor, op, nor->write_proto); diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 937d79af64e..88312a38338 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -401,15 +401,15 @@ static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX; if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.rdesc) { - /* - * Record current operation information which may be used - * when the address or data length exceeds address mapping. - */ - memcpy(&nor->dirmap.rdesc->info.op_tmpl, &op, - sizeof(struct spi_mem_op)); + struct spi_mem_op *tmp; + + /* temporary use another dirmap template */ + tmp = nor->dirmap.wdesc->info.op_tmpl; + nor->dirmap.rdesc->info.op_tmpl = &op; ret = spi_mem_dirmap_read(nor->dirmap.rdesc, op.addr.val, op.data.nbytes, op.data.buf.in); + nor->dirmap.rdesc->info.op_tmpl = tmp; if (ret < 0) return ret; op.data.nbytes = ret; @@ -447,10 +447,14 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, spi_nor_setup_op(nor, &op, nor->write_proto); if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.wdesc) { - memcpy(&nor->dirmap.wdesc->info.op_tmpl, &op, - sizeof(struct spi_mem_op)); + struct spi_mem_op *tmp; + + /* temporary use another dirmap template */ + tmp = nor->dirmap.wdesc->info.op_tmpl; + nor->dirmap.wdesc->info.op_tmpl = &op; op.data.nbytes = spi_mem_dirmap_write(nor->dirmap.wdesc, op.addr.val, op.data.nbytes, op.data.buf.out); + nor->dirmap.wdesc->info.op_tmpl = tmp; } else { ret = spi_mem_adjust_op_size(nor->spi, &op); if (ret) diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c index 769ec956793..30feaca25e6 100644 --- a/drivers/spi/airoha_snfi_spi.c +++ b/drivers/spi/airoha_snfi_spi.c @@ -545,7 +545,7 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) if (desc->info.length > SPI_NAND_CACHE_SIZE) return -E2BIG; - if (!airoha_snand_supports_op(desc->slave, &desc->info.op_tmpl)) + if (!airoha_snand_supports_op(desc->slave, desc->info.op_tmpl)) return -EOPNOTSUPP; return 0; @@ -565,7 +565,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, if (!priv->dma) { /* simplified version of spi_mem_no_dirmap_read() */ - struct spi_mem_op op = desc->info.op_tmpl; + struct spi_mem_op op = *desc->info.op_tmpl; op.addr.val = desc->info.offset + offs; op.data.buf.in = buf; @@ -584,7 +584,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, * DUALIO and QUADIO opcodes are not supported by the spi controller, * replace them with supported opcodes. */ - opcode = desc->info.op_tmpl.cmd.opcode; + opcode = desc->info.op_tmpl->cmd.opcode; switch (opcode) { case SPI_NAND_OP_READ_FROM_CACHE_SINGLE: case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST: @@ -767,7 +767,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, if (!priv->dma) { /* simplified version of spi_mem_no_dirmap_write() */ - struct spi_mem_op op = desc->info.op_tmpl; + struct spi_mem_op op = *desc->info.op_tmpl; op.addr.val = desc->info.offset + offs; op.data.buf.out = buf; @@ -782,7 +782,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, /* minimum oob size is 64 */ bytes = round_up(offs + len, 64); - opcode = desc->info.op_tmpl.cmd.opcode; + opcode = desc->info.op_tmpl->cmd.opcode; switch (opcode) { case SPI_NAND_OP_PROGRAM_LOAD_SINGLE: case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE: diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 0186b01ad9a..83eca25ecdd 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -732,13 +732,13 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) struct aspeed_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); const struct aspeed_spi_info *info = priv->info; - struct spi_mem_op op_tmpl = desc->info.op_tmpl; + struct spi_mem_op op_tmpl = *desc->info.op_tmpl; u32 i; u32 cs = slave_plat->cs[0]; u32 cmd_io_conf; uintptr_t ce_ctrl_reg; - if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) { + if (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT) { /* * dirmap_write is not supported currently due to a HW * limitation for command write mode: The written data @@ -795,12 +795,12 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, int ret; dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%zx\n", - desc->info.op_tmpl.cmd.opcode, offs, len); + desc->info.op_tmpl->cmd.opcode, offs, len); if (priv->flashes[cs].ahb_decoded_sz < offs + len || (offs % 4) != 0) { ret = aspeed_spi_exec_op_user_mode(desc->slave, - &desc->info.op_tmpl); + desc->info.op_tmpl); if (ret != 0) return 0; } else { diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 1c23f3d8843..351ca725524 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -572,7 +572,7 @@ EXPORT_SYMBOL_GPL(spi_mem_calc_op_duration); static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { - struct spi_mem_op op = desc->info.op_tmpl; + struct spi_mem_op op = *desc->info.op_tmpl; int ret; op.addr.val = desc->info.offset + offs; @@ -592,7 +592,7 @@ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, const void *buf) { - struct spi_mem_op op = desc->info.op_tmpl; + struct spi_mem_op op = *desc->info.op_tmpl; int ret; op.addr.val = desc->info.offset + offs; @@ -632,11 +632,11 @@ spi_mem_dirmap_create(struct spi_slave *slave, int ret = -EOPNOTSUPP; /* Make sure the number of address cycles is between 1 and 8 bytes. */ - if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8) + if (!info->primary_op_tmpl.addr.nbytes || info->primary_op_tmpl.addr.nbytes > 8) return ERR_PTR(-EINVAL); /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */ - if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA) + if (info->primary_op_tmpl.data.dir == SPI_MEM_NO_DATA) return ERR_PTR(-EINVAL); desc = kzalloc(sizeof(*desc), GFP_KERNEL); @@ -645,12 +645,13 @@ spi_mem_dirmap_create(struct spi_slave *slave, desc->slave = slave; desc->info = *info; + desc->info.op_tmpl = &desc->info.primary_op_tmpl; if (ops->mem_ops && ops->mem_ops->dirmap_create) ret = ops->mem_ops->dirmap_create(desc); if (ret) { desc->nodirmap = true; - if (!spi_mem_supports_op(desc->slave, &desc->info.op_tmpl)) + if (!spi_mem_supports_op(desc->slave, &desc->info.primary_op_tmpl)) ret = -EOPNOTSUPP; else ret = 0; @@ -778,7 +779,7 @@ ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, struct dm_spi_ops *ops = spi_get_ops(bus); ssize_t ret; - if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) + if (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN) return -EINVAL; if (!len) @@ -818,7 +819,7 @@ ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, struct dm_spi_ops *ops = spi_get_ops(bus); ssize_t ret; - if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT) + if (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_OUT) return -EINVAL; if (!len) diff --git a/include/spi-mem.h b/include/spi-mem.h index 8c20feebfca..81166492da2 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -211,7 +211,8 @@ struct spi_mem_op { * direction is directly encoded in the ->op_tmpl.data.dir field. */ struct spi_mem_dirmap_info { - struct spi_mem_op op_tmpl; + struct spi_mem_op *op_tmpl; + struct spi_mem_op primary_op_tmpl; u64 offset; u64 length; }; -- 2.53.0
