From patchwork Fri Sep 20 18:12:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Erez Geva X-Patchwork-Id: 1988017 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=bBvltD7y; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X9LMh73cNz1y34 for ; Sat, 21 Sep 2024 04:22:22 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zyi85Of6+sHBWjeHiuOwrmRBXdvq5mp3vCwk/8PvA00=; b=bBvltD7yK7s5Pt +RjgkkejqhlIO0rie797NuLh8r4qOa5cwp27H3Qgv8cH0uTAUzQL2eUOJbp5ivVY9fWYWp0ipC5tw r97EFOLodxBGVCi1byiUyPEezgZkGG1AJ6fSuEYXPOFhCx30q8reuDoHiCtXpat1b5Lg9wrLxG/p9 hlMbfzS7s0NRbcVN7yteXWX/1WFowbccDjqqEAmmUpZzmUQASoigNJKPJGMbplpiP+cfEm2I2xZAP t/37yyjQqV9Vqlplpo67zCw+wZaDxaaxlH1jgpFHnSewLskAJY+n2gUBsorsTHTm3+cqz+eM/8RYG 3Mxs5l4WoMXlGvDyg+/Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1sriGh-0000000CnOs-0lmW; Fri, 20 Sep 2024 18:22:11 +0000 Received: from chessie.fmt1.pfcs.com ([2001:470:1:205::234] helo=chessie.everett.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1sriGe-0000000CnMS-1ect for linux-mtd@lists.infradead.org; Fri, 20 Sep 2024 18:22:09 +0000 Received: from localhost.localdomain (ip-77-25-16-238.web.vodafone.de [77.25.16.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4X9L902clHzMR7l; Fri, 20 Sep 2024 18:13:08 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Esben Haabendal , Erez Geva Subject: [PATCH v5 2/5] mtd: spi-nor: core: add generic functions Date: Fri, 20 Sep 2024 20:12:28 +0200 Message-Id: <20240920181231.20542-3-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20240920181231.20542-1-erezgeva@nwtime.org> References: <20240920181231.20542-1-erezgeva@nwtime.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240920_112208_445949_F933B912 X-CRM114-Status: GOOD ( 15.50 ) X-Spam-Score: -1.9 (-) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Erez Geva Create a new internal function, spi_nor_send_cmd_internal() to reduce duplicate code. Add generic functions for use by vendor callbacks. The functions contain dispatching for using SPIMEM or using an SPI controller. It is better to leave this kind of dispatcher, out side of vendor spec [...] Content analysis details: (-1.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Erez Geva Create a new internal function, spi_nor_send_cmd_internal() to reduce duplicate code. Add generic functions for use by vendor callbacks. The functions contain dispatching for using SPIMEM or using an SPI controller. It is better to leave this kind of dispatcher, out side of vendor specific code. In this patch series we use the new functions in Macronix new OTP callbacks. The new added functions: - Send an opcode without address or data. - Read a register value. - Write a register value. Signed-off-by: Erez Geva --- drivers/mtd/spi-nor/core.c | 130 +++++++++++++++++++++++++++---------- drivers/mtd/spi-nor/core.h | 27 +------- 2 files changed, 99 insertions(+), 58 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0238475059f0..e486596fc70a 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -354,53 +354,134 @@ int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op, } /** - * spi_nor_write_enable() - Set write enable latch with Write Enable command. + * spi_nor_send_cmd_internal() - Send instruction without address or data to the chip. * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send * * Return: 0 on success, -errno otherwise. */ -int spi_nor_write_enable(struct spi_nor *nor) +static inline int spi_nor_send_cmd_internal(struct spi_nor *nor, u8 opcode) { int ret; if (nor->spimem) { - struct spi_mem_op op = SPI_NOR_WREN_OP; + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WREN, - NULL, 0); + ret = spi_nor_controller_ops_write_reg(nor, opcode, NULL, 0); } - if (ret) - dev_dbg(nor->dev, "error %d on Write Enable\n", ret); + return ret; +} + +/** + * spi_nor_send_cmd() - Send instruction without address or data to the chip. + * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode) +{ + int ret; + + ret = spi_nor_send_cmd_internal(nor, opcode); return ret; } /** - * spi_nor_write_disable() - Send Write Disable instruction to the chip. + * spi_nor_read_reg() - Send instruction without address or data to the chip. * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * @len: register value length * * Return: 0 on success, -errno otherwise. */ -int spi_nor_write_disable(struct spi_nor *nor) +int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len) { int ret; if (nor->spimem) { - struct spi_mem_op op = SPI_NOR_WRDI_OP; + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(len, nor->bouncebuf, 0)); spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WRDI, - NULL, 0); + ret = spi_nor_controller_ops_read_reg(nor, opcode, nor->bouncebuf, len); } + return ret; +} + +/* + * spi_nor_write_reg() - Send instruction without address or data to the chip. + * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * @len: register value length + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(len, nor->bouncebuf, 0)); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = spi_nor_controller_ops_write_reg(nor, opcode, nor->bouncebuf, len); + } + + return ret; +} + +/** + * spi_nor_write_enable() - Set write enable latch with Write Enable command. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_enable(struct spi_nor *nor) +{ + int ret; + + ret = spi_nor_send_cmd_internal(nor, SPINOR_OP_WREN); + + if (ret) + dev_dbg(nor->dev, "error %d on Write Enable\n", ret); + + return ret; +} + +/** + * spi_nor_write_disable() - Send Write Disable instruction to the chip. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_disable(struct spi_nor *nor) +{ + int ret; + + ret = spi_nor_send_cmd_internal(nor, SPINOR_OP_WRDI); + if (ret) dev_dbg(nor->dev, "error %d on Write Disable\n", ret); @@ -521,18 +602,8 @@ int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable) { int ret; - if (nor->spimem) { - struct spi_mem_op op = SPI_NOR_EN4B_EX4B_OP(enable); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_write_reg(nor, - enable ? SPINOR_OP_EN4B : - SPINOR_OP_EX4B, - NULL, 0); - } + ret = spi_nor_send_cmd_internal(nor, enable ? SPINOR_OP_EN4B : + SPINOR_OP_EX4B); if (ret) dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); @@ -765,16 +836,7 @@ int spi_nor_global_block_unlock(struct spi_nor *nor) if (ret) return ret; - if (nor->spimem) { - struct spi_mem_op op = SPI_NOR_GBULK_OP; - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_GBULK, - NULL, 0); - } + ret = spi_nor_send_cmd_internal(nor, SPINOR_OP_GBULK); if (ret) { dev_dbg(nor->dev, "error %d on Global Block Unlock\n", ret); diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index c862e42c844f..615c399dfb6e 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -25,18 +25,6 @@ SPI_MEM_OP_DUMMY(ndummy, 0), \ SPI_MEM_OP_DATA_IN(len, buf, 0)) -#define SPI_NOR_WREN_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - -#define SPI_NOR_WRDI_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_RDSR_OP(buf) \ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0), \ SPI_MEM_OP_NO_ADDR, \ @@ -67,24 +55,12 @@ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_IN(1, buf, 0)) -#define SPI_NOR_EN4B_EX4B_OP(enable) \ - SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_BRWR_OP(buf) \ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_BRWR, 0), \ SPI_MEM_OP_NO_ADDR, \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_OUT(1, buf, 0)) -#define SPI_NOR_GBULK_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_GBULK, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_DIE_ERASE_OP(opcode, addr_nbytes, addr, dice) \ SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \ SPI_MEM_OP_ADDR(dice ? addr_nbytes : 0, addr, 0), \ @@ -604,6 +580,9 @@ extern const struct attribute_group *spi_nor_sysfs_groups[]; void spi_nor_spimem_setup_op(const struct spi_nor *nor, struct spi_mem_op *op, const enum spi_nor_protocol proto); +int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode); +int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len); +int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len); int spi_nor_write_enable(struct spi_nor *nor); int spi_nor_write_disable(struct spi_nor *nor); int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable);