{"id":2230406,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2230406/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-aspeed/patch/20260429-winbond-v6-18-rc1-cont-read-v3-4-0f38b3c229ad@bootlin.com/","project":{"id":57,"url":"http://patchwork.ozlabs.org/api/1.1/projects/57/?format=json","name":"Linux ASPEED SoC development","link_name":"linux-aspeed","list_id":"linux-aspeed.lists.ozlabs.org","list_email":"linux-aspeed@lists.ozlabs.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260429-winbond-v6-18-rc1-cont-read-v3-4-0f38b3c229ad@bootlin.com>","date":"2026-04-29T17:56:41","name":"[v3,04/11] spi: spi-mem: Transform the read operation template","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"e31f0c4f11a0adc7b99f63cd8c9e534df6f5619f","submitter":{"id":73368,"url":"http://patchwork.ozlabs.org/api/1.1/people/73368/?format=json","name":"Miquel Raynal","email":"miquel.raynal@bootlin.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-aspeed/patch/20260429-winbond-v6-18-rc1-cont-read-v3-4-0f38b3c229ad@bootlin.com/mbox/","series":[{"id":502122,"url":"http://patchwork.ozlabs.org/api/1.1/series/502122/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-aspeed/list/?series=502122","date":"2026-04-29T17:56:39","name":"mtd: spinand: Winbond continuous read support","version":3,"mbox":"http://patchwork.ozlabs.org/series/502122/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2230406/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2230406/checks/","tags":{},"headers":{"Return-Path":"\n <linux-aspeed+bounces-3985-incoming=patchwork.ozlabs.org@lists.ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-aspeed@lists.ozlabs.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=zNm+Ffi/;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=112.213.38.117; helo=lists.ozlabs.org;\n envelope-from=linux-aspeed+bounces-3985-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)","lists.ozlabs.org;\n arc=none smtp.remote-ip=185.171.202.116","lists.ozlabs.org;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com","lists.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=zNm+Ffi/;\n\tdkim-atps=neutral","lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=bootlin.com\n (client-ip=185.171.202.116; helo=smtpout-04.galae.net;\n envelope-from=miquel.raynal@bootlin.com; receiver=lists.ozlabs.org)"],"Received":["from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5QCf6ZsGz1yHX\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 04:03:42 +1000 (AEST)","from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4g5QCb54Ldz2yjp;\n\tThu, 30 Apr 2026 04:03:39 +1000 (AEST)","from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4g5QCW1kvdz2yps;\n\tThu, 30 Apr 2026 04:03:34 +1000 (AEST)","from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233])\n\tby smtpout-04.galae.net (Postfix) with ESMTPS id 24059C5CD5E;\n\tWed, 29 Apr 2026 17:58:36 +0000 (UTC)","from mail.galae.net (mail.galae.net [212.83.136.155])\n\tby smtpout-01.galae.net (Postfix) with ESMTPS id E6A625FD43;\n\tWed, 29 Apr 2026 17:57:51 +0000 (UTC)","from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon)\n with ESMTPSA id 17C121072B158;\n\tWed, 29 Apr 2026 19:57:45 +0200 (CEST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1777485819;\n\tcv=none;\n b=RY1ZkKntHH9hMKzWIhanTIGMAgVgo1BtAlF0xyr1D9UHlx/9hciTssAndJUHuqcK/LegRgCXIcjmdC96J8snvcqPBK90UZn8I5HzZl28XoX2Gn9EU/HFL5BAAzn8sDpLHKb+Aa9V/s1YwuI6JKbl2NTjrfjezj+qiE5cufG5BGnfKB0fRcaxhccmuw2Ehn3D4g6VVH0qFHoirxvM9y3Vx/Zs4aa9dmnpivBM/a6B0Y3FL6u/E73kIy7ZIFSm+i0+x4kxkCwCbBLmDns5K2i/bEGmfS6nK6lWAX5cp/ah+khl71vfZllw17F35jY03tyCnOIB3v9cEcNOHmMuiej9Aw==","ARC-Message-Signature":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1777485819; c=relaxed/relaxed;\n\tbh=yFQWpGXRfJAmrHLeBgm6kc2xglR3Fv5EghBUWQsY1Nk=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=WHdLlDgi3QWPEWKq0ra9iirP//WUEtbiCZMJ7ai3+wi1qNVr4GPPdICTf4BMtDD3+XdzFrOLx+ifbCl7y/uz+/W1IJr53fbD09E8jHukAFyOFAVGXbhVxlrVFAo8I/MGjSsKxhraSwkgIu9GrZwaG3la/8VCqd0z8zOUpsZvJAviUWJa3oE/s7vTGLoVCTjoVdLkEexTFws3A6HolEf5OTk+LK6BEnhsK2H3meL3LMNcAxWjRyhEU2hG8EZbExEdqnexECKoZ3DvaFh7jxJaY5PSaM1pHzezxuLymRX5HB3epy7HeghFpfxmPYVZhXyXu5SyXs3bXdp7KgSs8hDhEA==","ARC-Authentication-Results":"i=1; lists.ozlabs.org;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com;\n dkim=pass (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=zNm+Ffi/; dkim-atps=neutral;\n spf=pass (client-ip=185.171.202.116; helo=smtpout-04.galae.net;\n envelope-from=miquel.raynal@bootlin.com;\n receiver=lists.ozlabs.org) smtp.mailfrom=bootlin.com","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim;\n\tt=1777485469; h=from:subject:date:message-id:to:cc:mime-version:content-type:\n\t content-transfer-encoding:in-reply-to:references;\n\tbh=yFQWpGXRfJAmrHLeBgm6kc2xglR3Fv5EghBUWQsY1Nk=;\n\tb=zNm+Ffi/6ezZMy6DwTh151pKgiOVgPBisspcIGedvwWOvv7SemEzu8DBkPpUArxO8wmQoy\n\tZqQbAdOmWkEicjB0O1pVZPCJQXWlMQ8/xJvhZ+7n19dEqoazFbxftEv4yRMx5aNzKEnMPX\n\tKylWMWcXOPO18qPUgkMbG9Z5FOckORYvQSAZgaXr0O80NSWv786732KYJZcEDVIjlAgWVD\n\tTb9SOVKOb7XC5m/pXCSKWz/+m4FlhTrIctcz/xTam0fS9fpRZ2A6BJNhZVnJC1SpNmNo1v\n\t8q9/YkjqOuh68v+E6lLH1hb2/aA2czHcWoLZTevUILsrN/I/gV9v76M/7Fbu2w==","From":"Miquel Raynal <miquel.raynal@bootlin.com>","Date":"Wed, 29 Apr 2026 19:56:41 +0200","Subject":"[PATCH v3 04/11] spi: spi-mem: Transform the read operation\n template","X-Mailing-List":"linux-aspeed@lists.ozlabs.org","List-Id":"<linux-aspeed.lists.ozlabs.org>","List-Help":"<mailto:linux-aspeed+help@lists.ozlabs.org>","List-Owner":"<mailto:linux-aspeed+owner@lists.ozlabs.org>","List-Post":"<mailto:linux-aspeed@lists.ozlabs.org>","List-Archive":"<https://lore.kernel.org/linux-aspeed/>,\n  <https://lists.ozlabs.org/pipermail/linux-aspeed/>","List-Subscribe":"<mailto:linux-aspeed+subscribe@lists.ozlabs.org>,\n  <mailto:linux-aspeed+subscribe-digest@lists.ozlabs.org>,\n  <mailto:linux-aspeed+subscribe-nomail@lists.ozlabs.org>","List-Unsubscribe":"<mailto:linux-aspeed+unsubscribe@lists.ozlabs.org>","Precedence":"list","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-Id":"\n <20260429-winbond-v6-18-rc1-cont-read-v3-4-0f38b3c229ad@bootlin.com>","References":"\n <20260429-winbond-v6-18-rc1-cont-read-v3-0-0f38b3c229ad@bootlin.com>","In-Reply-To":"\n <20260429-winbond-v6-18-rc1-cont-read-v3-0-0f38b3c229ad@bootlin.com>","To":"Mark Brown <broonie@kernel.org>, Richard Weinberger <richard@nod.at>,\n  Vignesh Raghavendra <vigneshr@ti.com>, Michael Walle <mwalle@kernel.org>,\n  Miquel Raynal <miquel.raynal@bootlin.com>,\n  Takahiro Kuwano <takahiro.kuwano@infineon.com>,\n  Lorenzo Bianconi <lorenzo@kernel.org>, Ray Liu <ray.liu@airoha.com>,\n  Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>, =?utf-8?q?C=C3=A9dric_Le_Goa?=\n\t=?utf-8?q?ter?= <clg@kaod.org>,  Joel Stanley <joel@jms.id.au>,\n Andrew Jeffery <andrew@codeconstruct.com.au>,\n  Avi Fishman <avifishman70@gmail.com>, Tomer Maimon <tmaimon77@gmail.com>,\n  Tali Perry <tali.perry1@gmail.com>, Patrick Venture <venture@google.com>,\n  Nancy Yuen <yuenn@google.com>, Benjamin Fair <benjaminfair@google.com>,\n  Maxime Coquelin <mcoquelin.stm32@gmail.com>,\n  Alexandre Torgue <alexandre.torgue@foss.st.com>, =?utf-8?q?Jonathan_Neusch?=\n\t=?utf-8?q?=C3=A4fer?= <j.neuschaefer@gmx.net>","Cc":"Pratyush Yadav <pratyush@kernel.org>,\n Thomas Petazzoni <thomas.petazzoni@bootlin.com>,\n Steam Lin <STLin2@winbond.com>, Santhosh Kumar K <s-k6@ti.com>,\n linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,\n linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org,\n linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org,\n linux-stm32@st-md-mailman.stormreply.com","X-Mailer":"b4 0.14.3","X-Last-TLS-Session-Version":"TLSv1.3","X-Spam-Status":"No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,\n\tDKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=disabled\n\tversion=4.0.1","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on lists.ozlabs.org"},"content":"As of now, we only use a single operation template when creating SPI\nmemory direct mappings. With the idea to extend this possibility to 2,\nrename the template to reflect that we are currently setting the\n\"primary\" operation, and create a pointer in the same structure to point\nto it.\n\nFrom a user point of view, the op_tmpl name remains but becomes a\npointer, leading to minor changes in both the SPI NAND and SPI NOR\ncores.\n\nThere is no functional change.\n\nAcked-by: Mark Brown <broonie@kernel.org>\nSigned-off-by: Miquel Raynal <miquel.raynal@bootlin.com>\n---\n drivers/mtd/nand/spi/core.c   | 15 ++++++++-------\n drivers/mtd/spi-nor/core.c    | 22 ++++++++++++----------\n drivers/spi/spi-airoha-snfi.c |  6 +++---\n drivers/spi/spi-aspeed-smc.c  |  4 ++--\n drivers/spi/spi-intel.c       |  6 +++---\n drivers/spi/spi-mem.c         | 15 ++++++++-------\n drivers/spi/spi-mxic.c        | 18 +++++++++---------\n drivers/spi/spi-npcm-fiu.c    | 16 ++++++++--------\n drivers/spi/spi-rpc-if.c      |  8 ++++----\n drivers/spi/spi-stm32-ospi.c  |  6 +++---\n drivers/spi/spi-stm32-qspi.c  |  6 +++---\n drivers/spi/spi-wpcm-fiu.c    |  2 +-\n include/linux/spi/spi-mem.h   |  3 ++-\n 13 files changed, 66 insertions(+), 61 deletions(-)","diff":"diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c\nindex 663f5d6a6bd7..a66510747b31 100644\n--- a/drivers/mtd/nand/spi/core.c\n+++ b/drivers/mtd/nand/spi/core.c\n@@ -491,9 +491,9 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,\n \n \tif (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED &&\n \t    req->mode != MTD_OPS_RAW)\n-\t\trdesc->info.op_tmpl.data.ecc = true;\n+\t\trdesc->info.op_tmpl->data.ecc = true;\n \telse\n-\t\trdesc->info.op_tmpl.data.ecc = false;\n+\t\trdesc->info.op_tmpl->data.ecc = false;\n \n \tif (spinand->flags & SPINAND_HAS_READ_PLANE_SELECT_BIT)\n \t\tcolumn |= req->pos.plane << fls(nanddev_page_size(nand));\n@@ -586,9 +586,9 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand,\n \n \tif (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED &&\n \t    req->mode != MTD_OPS_RAW)\n-\t\twdesc->info.op_tmpl.data.ecc = true;\n+\t\twdesc->info.op_tmpl->data.ecc = true;\n \telse\n-\t\twdesc->info.op_tmpl.data.ecc = false;\n+\t\twdesc->info.op_tmpl->data.ecc = false;\n \n \tif (spinand->flags & SPINAND_HAS_PROG_PLANE_SELECT_BIT)\n \t\tcolumn |= req->pos.plane << fls(nanddev_page_size(nand));\n@@ -1247,7 +1247,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand,\n \n \t/* Write descriptor */\n \tinfo.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);\n-\tinfo.op_tmpl.data.ecc = enable_ecc;\n+\tinfo.primary_op_tmpl = *spinand->op_templates->update_cache;\n+\tinfo.primary_op_tmpl.data.ecc = enable_ecc;\n \tdesc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,\n \t\t\t\t\t  spinand->spimem, &info);\n \tif (IS_ERR(desc))\n@@ -1256,8 +1257,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand,\n \tspinand->dirmaps[plane].wdesc = desc;\n \n \t/* Read descriptor */\n-\tinfo.op_tmpl = *spinand->op_templates->read_cache;\n-\tinfo.op_tmpl.data.ecc = enable_ecc;\n+\tinfo.primary_op_tmpl = *spinand->op_templates->read_cache;\n+\tinfo.primary_op_tmpl.data.ecc = enable_ecc;\n \tdesc = spinand_create_rdesc(spinand, &info);\n \tif (IS_ERR(desc))\n \t\treturn PTR_ERR(desc);\ndiff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c\nindex 5dd0b3cb5250..a7bc458edc5c 100644\n--- a/drivers/mtd/spi-nor/core.c\n+++ b/drivers/mtd/spi-nor/core.c\n@@ -3641,14 +3641,15 @@ EXPORT_SYMBOL_GPL(spi_nor_scan);\n static int spi_nor_create_read_dirmap(struct spi_nor *nor)\n {\n \tstruct spi_mem_dirmap_info info = {\n-\t\t.op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),\n-\t\t\t\t      SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),\n-\t\t\t\t      SPI_MEM_OP_DUMMY(nor->read_dummy, 0),\n-\t\t\t\t      SPI_MEM_OP_DATA_IN(0, NULL, 0)),\n+\t\t.op_tmpl = &info.primary_op_tmpl,\n+\t\t.primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),\n+\t\t\t\t\t      SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),\n+\t\t\t\t\t      SPI_MEM_OP_DUMMY(nor->read_dummy, 0),\n+\t\t\t\t\t      SPI_MEM_OP_DATA_IN(0, NULL, 0)),\n \t\t.offset = 0,\n \t\t.length = nor->params->size,\n \t};\n-\tstruct spi_mem_op *op = &info.op_tmpl;\n+\tstruct spi_mem_op *op = info.op_tmpl;\n \n \tspi_nor_spimem_setup_op(nor, op, nor->read_proto);\n \n@@ -3672,14 +3673,15 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor)\n static int spi_nor_create_write_dirmap(struct spi_nor *nor)\n {\n \tstruct spi_mem_dirmap_info info = {\n-\t\t.op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),\n-\t\t\t\t      SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),\n-\t\t\t\t      SPI_MEM_OP_NO_DUMMY,\n-\t\t\t\t      SPI_MEM_OP_DATA_OUT(0, NULL, 0)),\n+\t\t.op_tmpl = &info.primary_op_tmpl,\n+\t\t.primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),\n+\t\t\t\t\t      SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),\n+\t\t\t\t\t      SPI_MEM_OP_NO_DUMMY,\n+\t\t\t\t\t      SPI_MEM_OP_DATA_OUT(0, NULL, 0)),\n \t\t.offset = 0,\n \t\t.length = nor->params->size,\n \t};\n-\tstruct spi_mem_op *op = &info.op_tmpl;\n+\tstruct spi_mem_op *op = info.op_tmpl;\n \n \tif (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)\n \t\top->addr.nbytes = 0;\ndiff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c\nindex 7b6c09f91fef..95bfde7c8e7f 100644\n--- a/drivers/spi/spi-airoha-snfi.c\n+++ b/drivers/spi/spi-airoha-snfi.c\n@@ -546,7 +546,7 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \tif (desc->info.length > SPI_NAND_CACHE_SIZE)\n \t\treturn -E2BIG;\n \n-\tif (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl))\n+\tif (!airoha_snand_supports_op(desc->mem, desc->info.op_tmpl))\n \t\treturn -EOPNOTSUPP;\n \n \treturn 0;\n@@ -572,7 +572,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \t * DUALIO and QUADIO opcodes are not supported by the spi controller,\n \t * replace them with supported opcodes.\n \t */\n-\topcode = desc->info.op_tmpl.cmd.opcode;\n+\topcode = desc->info.op_tmpl->cmd.opcode;\n \tswitch (opcode) {\n \tcase SPI_NAND_OP_READ_FROM_CACHE_SINGLE:\n \tcase SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST:\n@@ -761,7 +761,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,\n \t/* minimum oob size is 64 */\n \tbytes = round_up(offs + len, 64);\n \n-\topcode = desc->info.op_tmpl.cmd.opcode;\n+\topcode = desc->info.op_tmpl->cmd.opcode;\n \tswitch (opcode) {\n \tcase SPI_NAND_OP_PROGRAM_LOAD_SINGLE:\n \tcase SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE:\ndiff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c\nindex c21323e07d3c..c20a33734f5c 100644\n--- a/drivers/spi/spi-aspeed-smc.c\n+++ b/drivers/spi/spi-aspeed-smc.c\n@@ -697,7 +697,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)\n {\n \tstruct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller);\n \tstruct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)];\n-\tstruct spi_mem_op *op = &desc->info.op_tmpl;\n+\tstruct spi_mem_op *op = desc->info.op_tmpl;\n \tu32 ctl_val;\n \tint ret = 0;\n \n@@ -769,7 +769,7 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \tif (chip->ahb_window_size < offset + len || chip->force_user_mode) {\n \t\tint ret;\n \n-\t\tret = aspeed_spi_read_user(chip, &desc->info.op_tmpl, offset, len, buf);\n+\t\tret = aspeed_spi_read_user(chip, desc->info.op_tmpl, offset, len, buf);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \t} else {\ndiff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c\nindex 1775ad39e633..7494b921a743 100644\n--- a/drivers/spi/spi-intel.c\n+++ b/drivers/spi/spi-intel.c\n@@ -814,7 +814,7 @@ static int intel_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \tstruct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);\n \tconst struct intel_spi_mem_op *iop;\n \n-\tiop = intel_spi_match_mem_op(ispi, &desc->info.op_tmpl);\n+\tiop = intel_spi_match_mem_op(ispi, desc->info.op_tmpl);\n \tif (!iop)\n \t\treturn -EOPNOTSUPP;\n \n@@ -827,7 +827,7 @@ static ssize_t intel_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs,\n {\n \tstruct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);\n \tconst struct intel_spi_mem_op *iop = desc->priv;\n-\tstruct spi_mem_op op = desc->info.op_tmpl;\n+\tstruct spi_mem_op op = *desc->info.op_tmpl;\n \tint ret;\n \n \t/* Fill in the gaps */\n@@ -844,7 +844,7 @@ static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs\n {\n \tstruct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);\n \tconst struct intel_spi_mem_op *iop = desc->priv;\n-\tstruct spi_mem_op op = desc->info.op_tmpl;\n+\tstruct spi_mem_op op = *desc->info.op_tmpl;\n \tint ret;\n \n \top.addr.val = offs;\ndiff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c\nindex a09371a075d2..e2eaa1ba4ff6 100644\n--- a/drivers/spi/spi-mem.c\n+++ b/drivers/spi/spi-mem.c\n@@ -647,7 +647,7 @@ EXPORT_SYMBOL_GPL(spi_mem_calc_op_duration);\n static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \t\t\t\t      u64 offs, size_t len, void *buf)\n {\n-\tstruct spi_mem_op op = desc->info.op_tmpl;\n+\tstruct spi_mem_op op = *desc->info.op_tmpl;\n \tint ret;\n \n \top.addr.val = desc->info.offset + offs;\n@@ -667,7 +667,7 @@ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,\n static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,\n \t\t\t\t       u64 offs, size_t len, const void *buf)\n {\n-\tstruct spi_mem_op op = desc->info.op_tmpl;\n+\tstruct spi_mem_op op = *desc->info.op_tmpl;\n \tint ret;\n \n \top.addr.val = desc->info.offset + offs;\n@@ -706,11 +706,11 @@ spi_mem_dirmap_create(struct spi_mem *mem,\n \tint ret = -ENOTSUPP;\n \n \t/* Make sure the number of address cycles is between 1 and 8 bytes. */\n-\tif (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)\n+\tif (!info->primary_op_tmpl.addr.nbytes || info->primary_op_tmpl.addr.nbytes > 8)\n \t\treturn ERR_PTR(-EINVAL);\n \n \t/* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */\n-\tif (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)\n+\tif (info->primary_op_tmpl.data.dir == SPI_MEM_NO_DATA)\n \t\treturn ERR_PTR(-EINVAL);\n \n \tdesc = kzalloc_obj(*desc);\n@@ -719,6 +719,7 @@ spi_mem_dirmap_create(struct spi_mem *mem,\n \n \tdesc->mem = mem;\n \tdesc->info = *info;\n+\tdesc->info.op_tmpl = &desc->info.primary_op_tmpl;\n \tif (ctlr->mem_ops && ctlr->mem_ops->dirmap_create) {\n \t\tret = spi_mem_access_start(mem);\n \t\tif (ret) {\n@@ -733,7 +734,7 @@ spi_mem_dirmap_create(struct spi_mem *mem,\n \n \tif (ret) {\n \t\tdesc->nodirmap = true;\n-\t\tif (!spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))\n+\t\tif (!spi_mem_supports_op(desc->mem, &desc->info.primary_op_tmpl))\n \t\t\tret = -EOPNOTSUPP;\n \t\telse\n \t\t\tret = 0;\n@@ -857,7 +858,7 @@ ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \tstruct spi_controller *ctlr = desc->mem->spi->controller;\n \tssize_t ret;\n \n-\tif (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)\n+\tif (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)\n \t\treturn -EINVAL;\n \n \tif (!len)\n@@ -903,7 +904,7 @@ ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,\n \tstruct spi_controller *ctlr = desc->mem->spi->controller;\n \tssize_t ret;\n \n-\tif (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT)\n+\tif (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_OUT)\n \t\treturn -EINVAL;\n \n \tif (!len)\ndiff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c\nindex b0e7fc828a50..83b688e65284 100644\n--- a/drivers/spi/spi-mxic.c\n+++ b/drivers/spi/spi-mxic.c\n@@ -403,20 +403,20 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \tif (WARN_ON(offs + desc->info.offset + len > U32_MAX))\n \t\treturn -EINVAL;\n \n-\twritel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),\n+\twritel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl->data.swap16),\n \t       mxic->regs + HC_CFG);\n \n-\twritel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),\n+\twritel(mxic_spi_mem_prep_op_cfg(desc->info.op_tmpl, len),\n \t       mxic->regs + LRD_CFG);\n \twritel(desc->info.offset + offs, mxic->regs + LRD_ADDR);\n \tlen = min_t(size_t, len, mxic->linear.size);\n \twritel(len, mxic->regs + LRD_RANGE);\n-\twritel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |\n+\twritel(LMODE_CMD0(desc->info.op_tmpl->cmd.opcode) |\n \t       LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |\n \t       LMODE_EN,\n \t       mxic->regs + LRD_CTRL);\n \n-\tif (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) {\n+\tif (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl->data.ecc) {\n \t\tret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine,\n \t\t\t\t\t\t      NAND_PAGE_READ,\n \t\t\t\t\t\t      mxic->linear.dma + offs);\n@@ -448,20 +448,20 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,\n \tif (WARN_ON(offs + desc->info.offset + len > U32_MAX))\n \t\treturn -EINVAL;\n \n-\twritel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),\n+\twritel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl->data.swap16),\n \t       mxic->regs + HC_CFG);\n \n-\twritel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),\n+\twritel(mxic_spi_mem_prep_op_cfg(desc->info.op_tmpl, len),\n \t       mxic->regs + LWR_CFG);\n \twritel(desc->info.offset + offs, mxic->regs + LWR_ADDR);\n \tlen = min_t(size_t, len, mxic->linear.size);\n \twritel(len, mxic->regs + LWR_RANGE);\n-\twritel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |\n+\twritel(LMODE_CMD0(desc->info.op_tmpl->cmd.opcode) |\n \t       LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |\n \t       LMODE_EN,\n \t       mxic->regs + LWR_CTRL);\n \n-\tif (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) {\n+\tif (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl->data.ecc) {\n \t\tret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine,\n \t\t\t\t\t\t      NAND_PAGE_WRITE,\n \t\t\t\t\t\t      mxic->linear.dma + offs);\n@@ -509,7 +509,7 @@ static int mxic_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \tif (desc->info.offset + desc->info.length > U32_MAX)\n \t\treturn -EINVAL;\n \n-\tif (!mxic_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))\n+\tif (!mxic_spi_mem_supports_op(desc->mem, desc->info.op_tmpl))\n \t\treturn -EOPNOTSUPP;\n \n \treturn 0;\ndiff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c\nindex 6617751009c3..4b825044038b 100644\n--- a/drivers/spi/spi-npcm-fiu.c\n+++ b/drivers/spi/spi-npcm-fiu.c\n@@ -299,11 +299,11 @@ static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,\n \t\tfor (i = 0 ; i < len ; i++)\n \t\t\t*(buf_rx + i) = ioread8(src + i);\n \t} else {\n-\t\tif (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||\n-\t\t    desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||\n-\t\t    desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||\n-\t\t    desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)\n-\t\t\tnpcm_fiu_set_drd(fiu, &desc->info.op_tmpl);\n+\t\tif (desc->info.op_tmpl->addr.buswidth != fiu->drd_op.addr.buswidth ||\n+\t\t    desc->info.op_tmpl->dummy.nbytes != fiu->drd_op.dummy.nbytes ||\n+\t\t    desc->info.op_tmpl->cmd.opcode != fiu->drd_op.cmd.opcode ||\n+\t\t    desc->info.op_tmpl->addr.nbytes != fiu->drd_op.addr.nbytes)\n+\t\t\tnpcm_fiu_set_drd(fiu, desc->info.op_tmpl);\n \n \t\tmemcpy_fromio(buf_rx, src, len);\n \t}\n@@ -609,7 +609,7 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \t}\n \n \tif (!fiu->spix_mode &&\n-\t    desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {\n+\t    desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT) {\n \t\tdesc->nodirmap = true;\n \t\treturn 0;\n \t}\n@@ -644,9 +644,9 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \t\t\t\t   NPCM_FIU_CFG_FIU_FIX);\n \t}\n \n-\tif (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {\n+\tif (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN) {\n \t\tif (!fiu->spix_mode)\n-\t\t\tnpcm_fiu_set_drd(fiu, &desc->info.op_tmpl);\n+\t\t\tnpcm_fiu_set_drd(fiu, desc->info.op_tmpl);\n \t\telse\n \t\t\tnpcm_fiux_set_direct_rd(fiu);\n \ndiff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c\nindex 6edc0c4db854..1ef7bd91b3b3 100644\n--- a/drivers/spi/spi-rpc-if.c\n+++ b/drivers/spi/spi-rpc-if.c\n@@ -83,7 +83,7 @@ static ssize_t xspi_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,\n \tif (offs + desc->info.offset + len > U32_MAX)\n \t\treturn -EINVAL;\n \n-\trpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);\n+\trpcif_spi_mem_prepare(desc->mem->spi, desc->info.op_tmpl, &offs, &len);\n \n \treturn xspi_dirmap_write(rpc->dev, offs, len, buf);\n }\n@@ -97,7 +97,7 @@ static ssize_t rpcif_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \tif (offs + desc->info.offset + len > U32_MAX)\n \t\treturn -EINVAL;\n \n-\trpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);\n+\trpcif_spi_mem_prepare(desc->mem->spi, desc->info.op_tmpl, &offs, &len);\n \n \treturn rpcif_dirmap_read(rpc->dev, offs, len, buf);\n }\n@@ -110,13 +110,13 @@ static int rpcif_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \tif (desc->info.offset + desc->info.length > U32_MAX)\n \t\treturn -EINVAL;\n \n-\tif (!rpcif_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))\n+\tif (!rpcif_spi_mem_supports_op(desc->mem, desc->info.op_tmpl))\n \t\treturn -EOPNOTSUPP;\n \n \tif (!rpc->dirmap)\n \t\treturn -EOPNOTSUPP;\n \n-\tif (!rpc->xspi && desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)\n+\tif (!rpc->xspi && desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)\n \t\treturn -EOPNOTSUPP;\n \n \treturn 0;\ndiff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c\nindex 4461c6e24b9e..5f5b3cd5d725 100644\n--- a/drivers/spi/spi-stm32-ospi.c\n+++ b/drivers/spi/spi-stm32-ospi.c\n@@ -602,11 +602,11 @@ static int stm32_ospi_dirmap_create(struct spi_mem_dirmap_desc *desc)\n {\n \tstruct stm32_ospi *ospi = spi_controller_get_devdata(desc->mem->spi->controller);\n \n-\tif (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)\n+\tif (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT)\n \t\treturn -EOPNOTSUPP;\n \n \t/* Should never happen, as mm_base == null is an error probe exit condition */\n-\tif (!ospi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)\n+\tif (!ospi->mm_base && desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN)\n \t\treturn -EOPNOTSUPP;\n \n \tif (!ospi->mm_size)\n@@ -633,7 +633,7 @@ static ssize_t stm32_ospi_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \t * spi_mem_op template with offs, len and *buf in  order to get\n \t * all needed transfer information into struct spi_mem_op\n \t */\n-\tmemcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));\n+\tmemcpy(&op, desc->info.op_tmpl, sizeof(struct spi_mem_op));\n \tdev_dbg(ospi->dev, \"%s len = 0x%zx offs = 0x%llx buf = 0x%p\\n\", __func__, len, offs, buf);\n \n \top.data.nbytes = len;\ndiff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c\nindex df1bbacec90a..e2a6a6eaf9b2 100644\n--- a/drivers/spi/spi-stm32-qspi.c\n+++ b/drivers/spi/spi-stm32-qspi.c\n@@ -506,11 +506,11 @@ static int stm32_qspi_dirmap_create(struct spi_mem_dirmap_desc *desc)\n {\n \tstruct stm32_qspi *qspi = spi_controller_get_devdata(desc->mem->spi->controller);\n \n-\tif (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)\n+\tif (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT)\n \t\treturn -EOPNOTSUPP;\n \n \t/* should never happen, as mm_base == null is an error probe exit condition */\n-\tif (!qspi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)\n+\tif (!qspi->mm_base && desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN)\n \t\treturn -EOPNOTSUPP;\n \n \tif (!qspi->mm_size)\n@@ -536,7 +536,7 @@ static ssize_t stm32_qspi_dirmap_read(struct spi_mem_dirmap_desc *desc,\n \t * spi_mem_op template with offs, len and *buf in  order to get\n \t * all needed transfer information into struct spi_mem_op\n \t */\n-\tmemcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));\n+\tmemcpy(&op, desc->info.op_tmpl, sizeof(struct spi_mem_op));\n \tdev_dbg(qspi->dev, \"%s len = 0x%zx offs = 0x%llx buf = 0x%p\\n\", __func__, len, offs, buf);\n \n \top.data.nbytes = len;\ndiff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c\nindex 0e26ff178505..cd78e927953d 100644\n--- a/drivers/spi/spi-wpcm-fiu.c\n+++ b/drivers/spi/spi-wpcm-fiu.c\n@@ -377,7 +377,7 @@ static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)\n \tstruct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);\n \tint cs = spi_get_chipselect(desc->mem->spi, 0);\n \n-\tif (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)\n+\tif (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)\n \t\treturn -EOPNOTSUPP;\n \n \t/*\ndiff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h\nindex c8e207522223..9a96ddace3eb 100644\n--- a/include/linux/spi/spi-mem.h\n+++ b/include/linux/spi/spi-mem.h\n@@ -237,7 +237,8 @@ struct spi_mem_op {\n  * direction is directly encoded in the ->op_tmpl.data.dir field.\n  */\n struct spi_mem_dirmap_info {\n-\tstruct spi_mem_op op_tmpl;\n+\tstruct spi_mem_op *op_tmpl;\n+\tstruct spi_mem_op primary_op_tmpl;\n \tu64 offset;\n \tu64 length;\n };\n","prefixes":["v3","04/11"]}