From patchwork Tue Mar 28 15:40:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191310 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AF18BC6FD18 for ; Tue, 28 Mar 2023 15:42:24 +0000 (UTC) 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=x5yztQBQvuWWesp+zkEsjLRnu7ueLJ6Bib5Nrjqqb5k=; b=IMF9fH1JnQKd++ Z61sjYDM2Gt5OY0qkmvxqSFq2hNGqAlpLFZydMWb+P3SVdk+0uI3IVXDJDLBw0TdmmJorB8fblTDn 5kZV4SHV1jejLYO+bceByW8vWK2gnfrO6G/PpqDUcbdBtB+bTgnjc9oop6Qr94fDbTZVVKsb6pvNi CeA+lAkSJj2IL6ELQFMK75sYElkzAETPQ7Aj8OvYMsAYvfLtihTSTisOqt35ROxkSlCEvrK4PJ+/S g9OfjntQ2kPvqbXnTwIuwnSHVQqlD8R4X8k2bsqjdgcUCta/JrOkTZX2H6PZCeErUNtlrx3av4wGa s4WuMTw3quTOsfVyH0xA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBRw-00EymG-0s; Tue, 28 Mar 2023 15:41:28 +0000 Received: from relay3-d.mail.gandi.net ([2001:4b98:dc4:8::223]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRi-00Eycs-2f; Tue, 28 Mar 2023 15:41:16 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id D312C6000E; Tue, 28 Mar 2023 15:41:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018070; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TweW83xYmxYwAjJCKDSfe9u18vP8Wfd1+Bvg2sYpDX8=; b=WUmXWRV+lVh32a4NKSbWhPCT/cScwtumIOsAqx7nf108BZrot/8Gg+5zKh172QYAr4zQa8 JGCGXexFFSdRdql4dtLAX8/veDIiqtmnzVZcmwGGgRDBbGHkaoLayDLa2jace9vTxVw98D 8T3Lr6fmoPNt9nuGtsg+ZfK/HqDdokxAYTlC60dY+S2MVw32AgBsaTs9MbQISfnLiNOhD2 BLLU7QuTQiSKuchc4pNU4f7Z0dB0oAwa6T8RTFR2MRoR9oIymD6qHDlG6CBx0K3+Wr06wi 3Iix6nvxXPMdaTdQGdxiAjKaIi/KyiDhXoGtLLxVC9G8hFuvzVZEIAu82k+vYQ== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 1/8] mtd: spi-nor: Introduce the concept of bank Date: Tue, 28 Mar 2023 17:40:58 +0200 Message-Id: <20230328154105.448540-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084115_159038_DE5C5D24 X-CRM114-Status: GOOD ( 14.98 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SPI NOR chips are made of pages, which gathered in small groups make (erase) sectors. Sectors, gathered together, make banks inside the chip. Until now, there was only one bank per device supported, but we are about to introduce support for new chips featuring several banks (up to 4 so far) where different operations may happen in parallel. Let's allow describing these additional bank parameters, and let's do this independently of any other value (like the number of sectors) with an absolute value. By default we consider that all chips have a single bank. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.c | 1 + drivers/mtd/spi-nor/core.h | 16 +++++++++++----- drivers/mtd/spi-nor/xilinx.c | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0a78045ca1d9..7d9ca799f767 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2583,6 +2583,7 @@ static void spi_nor_init_default_params(struct spi_nor *nor) /* Set SPI NOR sizes. */ params->writesize = 1; params->size = (u64)info->sector_size * info->n_sectors; + params->bank_size = div64_u64(params->size, info->n_banks); params->page_size = info->page_size; if (!(info->flags & SPI_NOR_NO_FR)) { diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 25423225c29d..db0e458810c7 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -336,7 +336,8 @@ struct spi_nor_otp { * by the spi_nor_fixups hooks, or dynamically when parsing the JESD216 * Serial Flash Discoverable Parameters (SFDP) tables. * - * @size: the flash memory density in bytes. + * @bank_size: the flash memory bank density in bytes. + * @size: the total flash memory density in bytes. * @writesize Minimal writable flash unit size. Defaults to 1. Set to * ECC unit size for ECC-ed flashes. * @page_size: the page size of the SPI NOR flash memory. @@ -374,6 +375,7 @@ struct spi_nor_otp { * @locking_ops: SPI NOR locking methods. */ struct spi_nor_flash_parameter { + u64 bank_size; u64 size; u32 writesize; u32 page_size; @@ -435,6 +437,7 @@ struct spi_nor_fixups { * @sector_size: the size listed here is what works with SPINOR_OP_SE, which * isn't necessarily called a "sector" by the vendor. * @n_sectors: the number of sectors. + * @n_banks: the number of banks. * @page_size: the flash's page size. * @addr_nbytes: number of address bytes to send. * @@ -495,6 +498,7 @@ struct flash_info { unsigned sector_size; u16 n_sectors; u16 page_size; + u8 n_banks; u8 addr_nbytes; bool parse_sfdp; @@ -540,24 +544,26 @@ struct flash_info { .id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \ .id_len = 6 -#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors) \ +#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks) \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ - .page_size = 256 + .page_size = 256, \ + .n_banks = (_n_banks) /* Used when the "_ext_id" is two bytes at most */ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors) \ SPI_NOR_ID((_jedec_id), (_ext_id)), \ - SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)), + SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors) \ SPI_NOR_ID6((_jedec_id), (_ext_id)), \ - SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)), + SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes) \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ .page_size = (_page_size), \ + .n_banks = 1, \ .addr_nbytes = (_addr_nbytes), \ .flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR, \ diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c index 5723157739fc..7175de8aa336 100644 --- a/drivers/mtd/spi-nor/xilinx.c +++ b/drivers/mtd/spi-nor/xilinx.c @@ -31,6 +31,7 @@ .sector_size = (8 * (_page_size)), \ .n_sectors = (_n_sectors), \ .page_size = (_page_size), \ + .n_banks = 1, \ .addr_nbytes = 3, \ .flags = SPI_NOR_NO_FR From patchwork Tue Mar 28 15:40:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191309 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E78A7C6FD18 for ; Tue, 28 Mar 2023 15:42:10 +0000 (UTC) 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=OIY9jQ5V2Of77G4tZJU+lTT6MEsFT3oy/+yYgeQ1enc=; b=zdPeF1UNsFJ3Aa mtpsJqz+5o/Imw5c/hXrG1ufn52OTUPmjhOCRk0QfFv+9WCoC5xUHjoophTEy907VSIdjwouhRZlb U73SNiyphGVZIn8IrlrGIVu6zcd6W4ODa05xtIIT65syVRWumePWFKsQeoQ5wnc8Bt/q+4t3FyGlp ds/X9WZair9wFpMwFYe2fFvE1iFQF3M1nmMu+erbLXMQrgljlcefbJnZO6qnld4CkmaQGXV/GfZks 7MliHRbK6/CxwPYv96Jw1fRvLqZ8PwbHFgEJUueCIlgZGTbsiqFcEgERSlblCvu+8wdTIUpNnHOXg Jr1gJSJ3lV5UcOrCl/eg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBRl-00Eyfh-2J; Tue, 28 Mar 2023 15:41:17 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRh-00EydH-2w; Tue, 28 Mar 2023 15:41:15 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id DF5DB60004; Tue, 28 Mar 2023 15:41:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018072; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r8+C50L6TyjhDk2JejbiwzuldSIgSHE+w4n/RI9WwcQ=; b=Nge901IZ139UsD3MGuFcxgzpK1cdTGtVkQcwLDDAj4QAr9N9eP5CHfapU0Gpkf4W56xOz4 BwVmhNxj3cdq2wc/wMxWkntcHWZOQSL+bLF9x1f3Tp/Ko2S54h9+7zmpjPuTGC3GtPDn4N j8bHYq9X11cdbKCOR8iABSXQGy/BVN7Z8qZWvOdP+8vNhhkTDxahNSF+ihCSSDFGuzscXv xy6CRZMrAXcR66HaUdY/GecJhhGw229VxhxBeBnfx1eKM8B8Ajs7dG+j+56mMc/MXircOq k1t/8vmPSdRcGFcZykicuA/bbIfQ2pWmVFsbCt6cfLXWaIk1TZZt4dpQ77ARaw== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 2/8] mtd: spi-nor: Add a macro to define more banks Date: Tue, 28 Mar 2023 17:40:59 +0200 Message-Id: <20230328154105.448540-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084114_079287_4FEA5E79 X-CRM114-Status: UNSURE ( 7.50 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Most of the chips on the market only feature a single bank. However, new chips may support more than a single bank, with the possibility to parallelize some operations. Let's introduce an INFOB() macro which also takes a n_bank parameter. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index db0e458810c7..bf2e64671856 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -555,6 +555,10 @@ struct flash_info { SPI_NOR_ID((_jedec_id), (_ext_id)), \ SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), +#define INFOB(_jedec_id, _ext_id, _sector_size, _n_sectors, _n_banks) \ + SPI_NOR_ID((_jedec_id), (_ext_id)), \ + SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), (_n_banks)), + #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors) \ SPI_NOR_ID6((_jedec_id), (_ext_id)), \ SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), From patchwork Tue Mar 28 15:41:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191312 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A26F8C76196 for ; Tue, 28 Mar 2023 15:42:37 +0000 (UTC) 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=XMSC8YdVKXQuZXtl6bizoe+wcbD2TpNpd0LfBRim9RM=; b=Q3oE1oisYsb5b+ H72vf/UeKgbY81qymQViNxUcGNn8hQMLhlzTw19mGlgEr3W3Kj5FFXXfCOv3emKM43DSnCERdk8Td WBRaLkUyXn/VUZcFGPnlqv97ob+gZY7Nt24H5ok/32wTAAbBekreQ0f9DFb4a5pBfmZhiooQYu2Fw LFVAEp9rV5lMMVBMQFcbfzJgZP1AkjsL0WvXfPhFATwzUEQ9GlRq90WUA354MgqbB6c+pnI61Xqft Ml/c1VZaL7Z6PPZHctwFo6QtDYKLaCfAh1hdA6O45/lyTiwP5WpfU3sQDtIowJFyMSIjsAS58nKF8 bgbZHy4E7nedZ12rFjpA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBS5-00Eyro-26; Tue, 28 Mar 2023 15:41:37 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRj-00Eye3-1t; Tue, 28 Mar 2023 15:41:17 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 9EF4B6000B; Tue, 28 Mar 2023 15:41:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018074; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m2kwOBPwszdSQgwOySfHyRaHUutXhyEyP6vkV70p3ME=; b=cb02EC4ocRqBK8FdytFlRY6n9Y6juGigWAVXK6jXAERYDg9gx9JIkL0SRfn8oRVm6SIZFZ /ITZXoGw1iJ/lSB0w44i44ESsu4FTssaxHQbSeDCsYL07OM0i1RyMyo9itEuAnrWeuTii7 zdy+YIS5JYn+VVDkN0VHVlSfbZJupuECrUBgl5OgYuI2oMIexuKC7vMslD+D/Dm9NxESMU /D+jgHMV71vw86vaHruyU3YLKrBpIfJNIOU0DKHjnoAxZzfX2/qdpUHI+QRI02vXz21vqq FOrvJYTUT+ya8RirUIk2qQyqipEAPBawrqmS1wULSh1kq6ZbIJ9bXLo0bw6Jkg== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 3/8] mtd: spi-nor: Reorder the preparation vs. locking steps Date: Tue, 28 Mar 2023 17:41:00 +0200 Message-Id: <20230328154105.448540-4-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084115_910623_9850DC5F X-CRM114-Status: GOOD ( 14.52 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The ->prepare()/->unprepare() hooks are now legacy, we no longer accept new drivers supporting them. The only remaining controllers using them acquires a per-chip mutex, which should not interfere with the rest of the operation done in the core. As a result, we should be safe to reorganize these helpers to first perform the preparation, before acquiring the core locks. This is necessary in order to be able to improve the locking mechanism in the core (coming next). No side effects are expected. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 23 ++++++++++------------- drivers/mtd/spi-nor/core.h | 2 +- drivers/mtd/spi-nor/otp.c | 8 ++++---- drivers/mtd/spi-nor/sst.c | 2 +- drivers/mtd/spi-nor/swp.c | 6 +++--- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 7d9ca799f767..3a7a407919e7 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1070,27 +1070,24 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) } } -int spi_nor_lock_and_prep(struct spi_nor *nor) +int spi_nor_prep_and_lock(struct spi_nor *nor) { int ret = 0; - mutex_lock(&nor->lock); - - if (nor->controller_ops && nor->controller_ops->prepare) { + if (nor->controller_ops && nor->controller_ops->prepare) ret = nor->controller_ops->prepare(nor); - if (ret) { - mutex_unlock(&nor->lock); - return ret; - } - } + + mutex_lock(&nor->lock); + return ret; } void spi_nor_unlock_and_unprep(struct spi_nor *nor) { + mutex_unlock(&nor->lock); + if (nor->controller_ops && nor->controller_ops->unprepare) nor->controller_ops->unprepare(nor); - mutex_unlock(&nor->lock); } static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr) @@ -1446,7 +1443,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr = instr->addr; len = instr->len; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -1706,7 +1703,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -1752,7 +1749,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index bf2e64671856..c4c78729ccea 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -647,7 +647,7 @@ int spi_nor_write_disable(struct spi_nor *nor); int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); int spi_nor_wait_till_ready(struct spi_nor *nor); int spi_nor_global_block_unlock(struct spi_nor *nor); -int spi_nor_lock_and_prep(struct spi_nor *nor); +int spi_nor_prep_and_lock(struct spi_nor *nor); void spi_nor_unlock_and_unprep(struct spi_nor *nor); int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor); int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor); diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c index 00ab0d2d6d2f..9a729aa3452d 100644 --- a/drivers/mtd/spi-nor/otp.c +++ b/drivers/mtd/spi-nor/otp.c @@ -255,7 +255,7 @@ static int spi_nor_mtd_otp_info(struct mtd_info *mtd, size_t len, if (len < n_regions * sizeof(*buf)) return -ENOSPC; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -325,7 +325,7 @@ static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs, if (!total_len) return 0; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -415,7 +415,7 @@ static int spi_nor_mtd_otp_erase(struct mtd_info *mtd, loff_t from, size_t len) if (!IS_ALIGNED(len, rlen) || !IS_ALIGNED(from, rlen)) return -EINVAL; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -460,7 +460,7 @@ static int spi_nor_mtd_otp_lock(struct mtd_info *mtd, loff_t from, size_t len) if (!IS_ALIGNED(len, rlen) || !IS_ALIGNED(from, rlen)) return -EINVAL; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c index 63bcc97bf978..688eb20c763e 100644 --- a/drivers/mtd/spi-nor/sst.c +++ b/drivers/mtd/spi-nor/sst.c @@ -126,7 +126,7 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len, dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 1f178313ba8f..0ba716e84377 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -348,7 +348,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -363,7 +363,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; @@ -378,7 +378,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret; - ret = spi_nor_lock_and_prep(nor); + ret = spi_nor_prep_and_lock(nor); if (ret) return ret; From patchwork Tue Mar 28 15:41:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191316 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 470A0C6FD18 for ; Tue, 28 Mar 2023 15:43:32 +0000 (UTC) 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=xLzDi99Vu4aCvvWYevibiO9YwwEW5aDuuknQzvVLggs=; b=EQnSY/E4LwsQFY fqHJhJZ6EgpPNGV9ZDViFJXKU1T+IN/73gy5ESa9iscjo4QE0ivO3vJNw2iusqTwMQuz3gkKSNk27 YGMOINTiyrt6KO/xf5bFF7iWBPFjeJON+8NHUS+H/iJEQHoPrl6UR2Z6fGQ1D8ZljjWMPlsx/xOuV h1d0sEf/s0C69v5PMuy2Usl2d7jcCdQ+DXG9gfMC1MgmqBUxF0lK1hr+OBzqd0jKQ8la1j7S0POI3 1qQVXIhP3vp1nr55KafNWwCeLyn/QaYf0rqTTs+AiISiwgRCuzuAFJrsuGotF+CNku44KbPe+GUs9 p4h9RsbVAHR1t+WTr6QQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBT3-00Ezfa-2M; Tue, 28 Mar 2023 15:42:37 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRl-00EyfG-1B; Tue, 28 Mar 2023 15:41:19 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 4C65E6000C; Tue, 28 Mar 2023 15:41:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018075; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E9olzw42GjrJ4I4m8VbHNu0ffDdliIC9s9nfHpP7fsw=; b=bFOW6VVc+KUz0ZdxJmGdkmFtpONFOOWwzbTXygvo4wAOFADw2leyjreiqD7F85axOOYLtx gwz1buCyb0Zstu10UL3ZoDxBmdy9Nyj1NgD/oTinYDoWsTUit5fM24HVDxDlhM/2QsXGpq 1MFfwUNxZdhk1Zj1XEX83kuYM9c5ko/YsXI4Nzon70IJheKF87fTQ1wRvmhlN/1AFdQL1S vqt0ScqRlPjFsX2oGCxUbP7O+95mkt1L0Vn1mn3zXdBZulRZeYz2lVeoX9DC32nkafoJGy BMkSBRKwO4xDCJ32u19C0GBqNOWgqIZeEBvCaQn8PWJ6VGGHWFm7oQGfxPHIPg== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 4/8] mtd: spi-nor: Separate preparation and locking Date: Tue, 28 Mar 2023 17:41:01 +0200 Message-Id: <20230328154105.448540-5-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084117_565762_95D4846C X-CRM114-Status: GOOD ( 10.32 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org While this operation will remain a single function call in the end, let's extract the logic of the [un]prepare calls within their own static helper. We will soon add new flavors of the *_[un]prepare_and_[un]lock() helpers, having the preparation logic outside will save us from duplicating code over and over again. There is no functional change. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 3a7a407919e7..e80677d36a8c 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1070,24 +1070,40 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) } } -int spi_nor_prep_and_lock(struct spi_nor *nor) +static int spi_nor_prep(struct spi_nor *nor) { int ret = 0; if (nor->controller_ops && nor->controller_ops->prepare) ret = nor->controller_ops->prepare(nor); + return ret; +} + +static void spi_nor_unprep(struct spi_nor *nor) +{ + if (nor->controller_ops && nor->controller_ops->unprepare) + nor->controller_ops->unprepare(nor); +} + +int spi_nor_prep_and_lock(struct spi_nor *nor) +{ + int ret; + + ret = spi_nor_prep(nor); + if (ret) + return ret; + mutex_lock(&nor->lock); - return ret; + return 0; } void spi_nor_unlock_and_unprep(struct spi_nor *nor) { mutex_unlock(&nor->lock); - if (nor->controller_ops && nor->controller_ops->unprepare) - nor->controller_ops->unprepare(nor); + spi_nor_unprep(nor); } static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr) From patchwork Tue Mar 28 15:41:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 41E34C76196 for ; Tue, 28 Mar 2023 15:43:46 +0000 (UTC) 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=QgE3sPUh43vCOtZVfZsCM9W4o18RoAzR6Zp5yCgYq+Q=; b=iNgXmqnMyoqNwY jzb4WPjSXLAHm4tXQ36yKkQN0CYIhjH1geiKBz4jqpHdJh0KhBJ313penKJDm+67mC3WozP+eajAu YGZBqTdNN7mwzgTsot5Mi5IQsmRQKerocYxO40ffK0gom2A3tU19xikHCNO+xt3j1Fmef17QEA5uY 4Gp+G5w9EZfF4Oyk/I7GKjIhByDM07TQ0xds6o5gFo8V/OROMU+afkXNaf/SZol4PzWv78Qm10YBh pRKz7/EH1fhFSzOfA+Xyr3kJ8BWIIPjx2uOqJ3CWaya6d/5azbdd9R6ZiumV917z90zgKIUR2L8wN h2bg54RYV1vt57EouCqA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBTI-00Eztc-1b; Tue, 28 Mar 2023 15:42:52 +0000 Received: from relay3-d.mail.gandi.net ([2001:4b98:dc4:8::223]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRn-00Eygd-27; Tue, 28 Mar 2023 15:41:22 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 1F64B60007; Tue, 28 Mar 2023 15:41:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=f44Jt6ki3YZzVQv+c39mwH925zrn6cTrzM5orWtRgts=; b=br7IKpspyyoFU0HMnU6mdnDtBhqkR6X+KdjbWHuF8KPqbPvvx+i9X1tREJn/AUHwmdFNYu aLjvu72jDR7CbOnF8NBTlL9cGoXDZuI6ujOCIheKJurl9sK6uiN0qVPUO50evzb6HxcpIH bxwf4sz7TguVoWhk8H287V9Z1ch04LeHGdRtNZjjPmNSlVyh5QDKG23wMcGAzqq4MAuxmR RHU+f50bAzWuoa29vNmo0520k8y9Kb/wk6pjGSktPpXR4hMNdST5CUU6VlzgpM3dzhOCEt irmbdH5OmT0ALU6mlcmFVixTp/U6kZBUQMEEthf2vloXkm0Ppm5DVnIIeU+cQA== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 5/8] mtd: spi-nor: Prepare the introduction of a new locking mechanism Date: Tue, 28 Mar 2023 17:41:02 +0200 Message-Id: <20230328154105.448540-6-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084120_029566_EC25BCDF X-CRM114-Status: GOOD ( 13.57 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This commit alone just introduces two new "prepare and lock" pairs of helpers which do the exact same thing as before. They will soon be improved in a followup commit which actually brings the logic, but I figured out it was more readable to do it this way. One new pair is suffixed _pe which stands for "program and erase" and hence is being called by spi_nor_write() and spi_nor_erase(). The other pair is suffixed _rd which stands for "read" and hence is being called by spi_nor_read(). One note however, these extra helpers will need to know the operation range, so they come with two new parameters to define it. Otherwise there is no functional change. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 59 ++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index e80677d36a8c..daed09950ee1 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1086,6 +1086,7 @@ static void spi_nor_unprep(struct spi_nor *nor) nor->controller_ops->unprepare(nor); } +/* Generic helpers for internal locking and serialization */ int spi_nor_prep_and_lock(struct spi_nor *nor) { int ret; @@ -1106,6 +1107,48 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor) spi_nor_unprep(nor); } +/* Internal locking helpers for program and erase operations */ +static int spi_nor_prep_and_lock_pe(struct spi_nor *nor, loff_t start, size_t len) +{ + int ret; + + ret = spi_nor_prep(nor); + if (ret) + return ret; + + mutex_lock(&nor->lock); + + return 0; +} + +static void spi_nor_unlock_and_unprep_pe(struct spi_nor *nor, loff_t start, size_t len) +{ + mutex_unlock(&nor->lock); + + spi_nor_unprep(nor); +} + +/* Internal locking helpers for read operations */ +static int spi_nor_prep_and_lock_rd(struct spi_nor *nor, loff_t start, size_t len) +{ + int ret; + + ret = spi_nor_prep(nor); + if (ret) + return ret; + + mutex_lock(&nor->lock); + + return 0; +} + +static void spi_nor_unlock_and_unprep_rd(struct spi_nor *nor, loff_t start, size_t len) +{ + mutex_unlock(&nor->lock); + + spi_nor_unprep(nor); +} + static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr) { if (!nor->params->convert_addr) @@ -1459,7 +1502,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr = instr->addr; len = instr->len; - ret = spi_nor_prep_and_lock(nor); + ret = spi_nor_prep_and_lock_pe(nor, instr->addr, instr->len); if (ret) return ret; @@ -1522,7 +1565,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) ret = spi_nor_write_disable(nor); erase_err: - spi_nor_unlock_and_unprep(nor); + spi_nor_unlock_and_unprep_pe(nor, instr->addr, instr->len); return ret; } @@ -1715,11 +1758,13 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct spi_nor *nor = mtd_to_spi_nor(mtd); + loff_t from_lock = from; + size_t len_lock = len; ssize_t ret; dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); - ret = spi_nor_prep_and_lock(nor); + ret = spi_nor_prep_and_lock_rd(nor, from_lock, len_lock); if (ret) return ret; @@ -1746,7 +1791,8 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, ret = 0; read_err: - spi_nor_unlock_and_unprep(nor); + spi_nor_unlock_and_unprep_rd(nor, from_lock, len_lock); + return ret; } @@ -1765,7 +1811,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); - ret = spi_nor_prep_and_lock(nor); + ret = spi_nor_prep_and_lock_pe(nor, to, len); if (ret) return ret; @@ -1807,7 +1853,8 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, } write_err: - spi_nor_unlock_and_unprep(nor); + spi_nor_unlock_and_unprep_pe(nor, to, len); + return ret; } From patchwork Tue Mar 28 15:41:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191313 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2D2F6C76196 for ; Tue, 28 Mar 2023 15:42:59 +0000 (UTC) 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=t0lm5QqXEJBlKn8jLJUZwlsMTI8Zdvbqwsw7HtUjMYo=; b=SMWplI3JfNm40g AdS1sR+e8NJXCubLEOKIK3f9t31J3GsHFr2ZFY5yvMldM0WliG+1dO8Dk9tiJQW6UdAVwRGQLfvT+ E8QxtdMzike4gf8pHHuN0RvIOrjiUBAYDqfI4EiayMpBMXz9VIgoyu29M4QEnIh6ATp795QPPHDLq DbYjdHw83ZGWqKduTLCzkxf0aEHqqERVrB7ETNkhole1KeHVHenIWxmZQ5x7jhleng0mMZjxrbXPo KDlrWBG3+Wjcotju1W3/OF/KRqYP8daHiQPcq5+h73SwhHcv2pi2seWC5509JmNGsl1f2EBNBEYm3 8Qpq8JNzkgaBFta89zFQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBSW-00EzEj-0U; Tue, 28 Mar 2023 15:42:04 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRp-00Eyhl-0e; Tue, 28 Mar 2023 15:41:24 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0E8D56000F; Tue, 28 Mar 2023 15:41:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018079; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ll9laDylLlA3Vjk2Q3vsPWAQBy04WBguwL1IDbn2b+U=; b=YMDRO2iuGlanMTchSo8vhCQyyf3bnnNkN/pQP1oS2BS58cZ+r6DbTWsPgfqEU1J7+EWOHE VGfkgR7F0D50IlLd2YYhqI2mvVhEEIOMKwcoFg8npG2yM4prd8vllWktyZaQTpdsTwOnfw fIdVXqSt8QxfAaCOduHjUnZ5P8kgt1KIpJzhwOS0YwK7/tmh6g5epdjkAOivI1b8H+apvN d4sJxdqUFAFORt9ZibVcXVtS+ss2UpNLEVCYKivKyiSjCs9y3mSmwAkhW6O6W4yptBTkql KF/BVr1mRujMyhLaBDw3hpBHhoY5NtWO0rR8aZQ8uOOagTiPhbUQvQVJ2stpAA== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 6/8] mtd: spi-nor: Add a RWW flag Date: Tue, 28 Mar 2023 17:41:03 +0200 Message-Id: <20230328154105.448540-7-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084121_551589_0C7D5C06 X-CRM114-Status: GOOD ( 12.72 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Introduce a new (no SFDP) flag for the feature that we are about to support: Read While Write. This means, if the chip has several banks and supports RWW, once a page of data to write has been transferred into the chip's internal SRAM, another read operation happening on a different bank can be performed during the tPROG delay. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 3 +++ drivers/mtd/spi-nor/core.h | 3 +++ drivers/mtd/spi-nor/debugfs.c | 1 + 3 files changed, 7 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index daed09950ee1..75ec7a3d0b43 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2530,6 +2530,9 @@ static void spi_nor_init_flags(struct spi_nor *nor) if (flags & NO_CHIP_ERASE) nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; + + if (flags & SPI_NOR_RWW) + nor->flags |= SNOR_F_RWW; } /** diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index c4c78729ccea..de31e430f77e 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -130,6 +130,7 @@ enum spi_nor_option_flags { SNOR_F_IO_MODE_EN_VOLATILE = BIT(11), SNOR_F_SOFT_RESET = BIT(12), SNOR_F_SWP_IS_VOLATILE = BIT(13), + SNOR_F_RWW = BIT(14), }; struct spi_nor_read_command { @@ -462,6 +463,7 @@ struct spi_nor_fixups { * NO_CHIP_ERASE: chip does not support chip erase. * SPI_NOR_NO_FR: can't do fastread. * SPI_NOR_QUAD_PP: flash supports Quad Input Page Program. + * SPI_NOR_RWW: flash supports reads while write. * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. * Used when SFDP tables are not defined in the flash. These @@ -513,6 +515,7 @@ struct flash_info { #define NO_CHIP_ERASE BIT(7) #define SPI_NOR_NO_FR BIT(8) #define SPI_NOR_QUAD_PP BIT(9) +#define SPI_NOR_RWW BIT(10) u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index 845b78c7ecc7..e200f5b9234c 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -25,6 +25,7 @@ static const char *const snor_f_names[] = { SNOR_F_NAME(IO_MODE_EN_VOLATILE), SNOR_F_NAME(SOFT_RESET), SNOR_F_NAME(SWP_IS_VOLATILE), + SNOR_F_NAME(RWW), }; #undef SNOR_F_NAME From patchwork Tue Mar 28 15:41:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191314 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4B13DC76196 for ; Tue, 28 Mar 2023 15:43:14 +0000 (UTC) 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=+NDKKeBRs0ZOxFNc/B6SrhQKzCroE9s1mocCgkZXv0w=; b=SyoVBFsvBoU0E1 yxEL/YbFX1J/HLADPOXacqF1m49UrlfYuJaBgsi+q8v98sVSU3zL89N/VdvdBftyPPt5QlIy3AB3l s7fZdXAWIx+DsloEb0Nn+hZvDLGGazWF321E81J6iUEo6IcQssetXU0KiuUscKyLb7gkuPTZ+5nbD fiQQRZHD5g3BDBGFWZGvXgPCdzzMSIOPuP3pjLWzYKE9c8BV9OVfCtPiNCIh19QUQYxnSWKVqdxY6 9WYbSFXOasI+CBt0u1qhITBqVTM5llwVs4alffy4I0jsCuBJSCCGLFTCgFyw+iJIQ518q6KyDk029 Mh8yAZhymTJajB2alOUQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBSi-00EzNy-0i; Tue, 28 Mar 2023 15:42:16 +0000 Received: from relay3-d.mail.gandi.net ([2001:4b98:dc4:8::223]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRr-00Eyj3-2E; Tue, 28 Mar 2023 15:41:27 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id E2CE06000B; Tue, 28 Mar 2023 15:41:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018081; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9SP0ivHMA90jI57HFcK/Xni+WiKFBXiGWUcZv/v7SmU=; b=B6KQDZvLsaElZr1WIzkKz2TwwjuXM/4pNahNQbTPp9xApY2wSQZ0wNJvRV1Fz9LsX6ryyy nv2HL7aa5LcXV6FCkRxOfvUiWu8f4GBAtn93WFRVgBSWyEC9mgsqcsdt31YB5rvIZYJ6Rp tm+XWSbzxWwAP6JqPlxzFqcUIeRdIWtdT0TKxF6ytWOPIJtWYrnnpYaudH4Nw6yHD5z1oN CLYvnPSDbMvElH00RqgVI1MddURtC9/ofowcGAPTBh0TBFynqYge9fFNisDW6dvNPhi/Zu VMRxUIBeu3tKUpCRFC8E3zcnI+WwnXoTM3K9E0pe237zZmMVIGI5d9kWtQzBPw== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 7/8] mtd: spi-nor: Enhance locking to support reads while writes Date: Tue, 28 Mar 2023 17:41:04 +0200 Message-Id: <20230328154105.448540-8-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084124_085935_FF3B8007 X-CRM114-Status: GOOD ( 29.28 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On devices featuring several banks, the Read While Write (RWW) feature is here to improve the overall performance when performing parallel reads and writes at different locations (different banks). The following constraints have to be taken into account: 1#: A single operation can be performed in a given bank. 2#: Only a single program or erase operation can happen on the entire chip (common hardware limitation to limit costs) 3#: Reads must remain serialized even though reads crossing bank boundaries are allowed. 4#: The I/O bus is unique and thus is the most constrained resource, all spi-nor operations requiring access to the spi bus (through the spi controller) must be serialized until the bus exchanges are over. So we must ensure a single operation can be "sent" at a time. 5#: Any other operation that would not be either a read or a write or an erase is considered requiring access to the full chip and cannot be parallelized, we then need to ensure the full chip is in the idle state when this occurs. All these constraints can easily be managed with a proper locking model: 1#: Is enforced by a bitfield of the in-use banks, so that only a single operation can happen in a specific bank at any time. 2#: Is handled by the ongoing_pe boolean which is set before any write or erase, and is released only at the very end of the operation. This way, no other destructive operation on the chip can start during this time frame. 3#: An ongoing_rd boolean allows to track the ongoing reads, so that only one can be performed at a time. 4#: An ongoing_io boolean is introduced in order to capture and serialize bus accessed. This is the one being released "sooner" than before, because we only need to protect the chip against other SPI accesses during the I/O phase, which for the destructive operations is the beginning of the operation (when we send the command cycles and possibly the data), while the second part of the operation (the erase delay or the programmation delay) is when we can do something else in another bank. 5#: Is handled by the three booleans presented above, if any of them is set, the chip is not yet ready for the operation and must wait. All these internal variables are protected by the existing lock, so that changes in this structure are atomic. The serialization is handled with a wait queue. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 337 ++++++++++++++++++++++++++++++++++-- include/linux/mtd/spi-nor.h | 13 ++ 2 files changed, 334 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 75ec7a3d0b43..9e6a0730cdb8 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -588,6 +588,65 @@ int spi_nor_sr_ready(struct spi_nor *nor) return !(nor->bouncebuf[0] & SR_WIP); } +/** + * spi_nor_use_parallel_locking() - Checks if RWW locking scheme shall be used + * @nor: pointer to 'struct spi_nor'. + * + * Return: true if parallel locking is enabled, false otherwise. + */ +static bool spi_nor_use_parallel_locking(struct spi_nor *nor) +{ + return nor->flags & SNOR_F_RWW; +} + +/* Locking helpers for status read operations */ +static int spi_nor_rww_start_rdst(struct spi_nor *nor) +{ + struct spi_nor_rww *rww = &nor->rww; + int ret = -EAGAIN; + + mutex_lock(&nor->lock); + + if (rww->ongoing_io || rww->ongoing_rd) + goto busy; + + rww->ongoing_io = true; + rww->ongoing_rd = true; + ret = 0; + +busy: + mutex_unlock(&nor->lock); + return ret; +} + +static void spi_nor_rww_end_rdst(struct spi_nor *nor) +{ + struct spi_nor_rww *rww = &nor->rww; + + mutex_lock(&nor->lock); + + rww->ongoing_io = false; + rww->ongoing_rd = false; + + mutex_unlock(&nor->lock); +} + +static int spi_nor_lock_rdst(struct spi_nor *nor) +{ + if (spi_nor_use_parallel_locking(nor)) + return spi_nor_rww_start_rdst(nor); + + return 0; +} + +static void spi_nor_unlock_rdst(struct spi_nor *nor) +{ + if (spi_nor_use_parallel_locking(nor)) { + spi_nor_rww_end_rdst(nor); + wake_up(&nor->rww.wait); + } +} + /** * spi_nor_ready() - Query the flash to see if it is ready for new commands. * @nor: pointer to 'struct spi_nor'. @@ -596,11 +655,21 @@ int spi_nor_sr_ready(struct spi_nor *nor) */ static int spi_nor_ready(struct spi_nor *nor) { + int ret; + + ret = spi_nor_lock_rdst(nor); + if (ret) + return 0; + /* Flashes might override the standard routine. */ if (nor->params->ready) - return nor->params->ready(nor); + ret = nor->params->ready(nor); + else + ret = spi_nor_sr_ready(nor); - return spi_nor_sr_ready(nor); + spi_nor_unlock_rdst(nor); + + return ret; } /** @@ -1086,7 +1155,88 @@ static void spi_nor_unprep(struct spi_nor *nor) nor->controller_ops->unprepare(nor); } +static void spi_nor_offset_to_banks(u64 bank_size, loff_t start, size_t len, + u8 *first, u8 *last) +{ + /* This is currently safe, the number of banks being very small */ + *first = DIV_ROUND_DOWN_ULL(start, bank_size); + *last = DIV_ROUND_DOWN_ULL(start + len - 1, bank_size); +} + /* Generic helpers for internal locking and serialization */ +static bool spi_nor_rww_start_io(struct spi_nor *nor) +{ + struct spi_nor_rww *rww = &nor->rww; + bool start = false; + + mutex_lock(&nor->lock); + + if (rww->ongoing_io) + goto busy; + + rww->ongoing_io = true; + start = true; + +busy: + mutex_unlock(&nor->lock); + return start; +} + +static void spi_nor_rww_end_io(struct spi_nor *nor) +{ + mutex_lock(&nor->lock); + nor->rww.ongoing_io = false; + mutex_unlock(&nor->lock); +} + +static int spi_nor_lock_device(struct spi_nor *nor) +{ + if (!spi_nor_use_parallel_locking(nor)) + return 0; + + return wait_event_killable(nor->rww.wait, spi_nor_rww_start_io(nor)); +} + +static void spi_nor_unlock_device(struct spi_nor *nor) +{ + if (spi_nor_use_parallel_locking(nor)) { + spi_nor_rww_end_io(nor); + wake_up(&nor->rww.wait); + } +} + +/* Generic helpers for internal locking and serialization */ +static bool spi_nor_rww_start_exclusive(struct spi_nor *nor) +{ + struct spi_nor_rww *rww = &nor->rww; + bool start = false; + + mutex_lock(&nor->lock); + + if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe) + goto busy; + + rww->ongoing_io = true; + rww->ongoing_rd = true; + rww->ongoing_pe = true; + start = true; + +busy: + mutex_unlock(&nor->lock); + return start; +} + +static void spi_nor_rww_end_exclusive(struct spi_nor *nor) +{ + struct spi_nor_rww *rww = &nor->rww; + + mutex_lock(&nor->lock); + rww->ongoing_io = false; + rww->ongoing_rd = false; + rww->ongoing_pe = false; + mutex_unlock(&nor->lock); +} + int spi_nor_prep_and_lock(struct spi_nor *nor) { int ret; @@ -1095,19 +1245,75 @@ int spi_nor_prep_and_lock(struct spi_nor *nor) if (ret) return ret; - mutex_lock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) + mutex_lock(&nor->lock); + else + ret = wait_event_killable(nor->rww.wait, + spi_nor_rww_start_exclusive(nor)); - return 0; + return ret; } void spi_nor_unlock_and_unprep(struct spi_nor *nor) { - mutex_unlock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) { + mutex_unlock(&nor->lock); + } else { + spi_nor_rww_end_exclusive(nor); + wake_up(&nor->rww.wait); + } spi_nor_unprep(nor); } /* Internal locking helpers for program and erase operations */ +static bool spi_nor_rww_start_pe(struct spi_nor *nor, loff_t start, size_t len) +{ + struct spi_nor_rww *rww = &nor->rww; + unsigned int used_banks = 0; + bool started = false; + u8 first, last; + int bank; + + mutex_lock(&nor->lock); + + if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe) + goto busy; + + spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last); + for (bank = first; bank <= last; bank++) { + if (rww->used_banks & BIT(bank)) + goto busy; + + used_banks |= BIT(bank); + } + + rww->used_banks |= used_banks; + rww->ongoing_pe = true; + started = true; + +busy: + mutex_unlock(&nor->lock); + return started; +} + +static void spi_nor_rww_end_pe(struct spi_nor *nor, loff_t start, size_t len) +{ + struct spi_nor_rww *rww = &nor->rww; + u8 first, last; + int bank; + + mutex_lock(&nor->lock); + + spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last); + for (bank = first; bank <= last; bank++) + rww->used_banks &= ~BIT(bank); + + rww->ongoing_pe = false; + + mutex_unlock(&nor->lock); +} + static int spi_nor_prep_and_lock_pe(struct spi_nor *nor, loff_t start, size_t len) { int ret; @@ -1116,19 +1322,77 @@ static int spi_nor_prep_and_lock_pe(struct spi_nor *nor, loff_t start, size_t le if (ret) return ret; - mutex_lock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) + mutex_lock(&nor->lock); + else + ret = wait_event_killable(nor->rww.wait, + spi_nor_rww_start_pe(nor, start, len)); - return 0; + return ret; } static void spi_nor_unlock_and_unprep_pe(struct spi_nor *nor, loff_t start, size_t len) { - mutex_unlock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) { + mutex_unlock(&nor->lock); + } else { + spi_nor_rww_end_pe(nor, start, len); + wake_up(&nor->rww.wait); + } spi_nor_unprep(nor); } /* Internal locking helpers for read operations */ +static bool spi_nor_rww_start_rd(struct spi_nor *nor, loff_t start, size_t len) +{ + struct spi_nor_rww *rww = &nor->rww; + unsigned int used_banks = 0; + bool started = false; + u8 first, last; + int bank; + + mutex_lock(&nor->lock); + + if (rww->ongoing_io || rww->ongoing_rd) + goto busy; + + spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last); + for (bank = first; bank <= last; bank++) { + if (rww->used_banks & BIT(bank)) + goto busy; + + used_banks |= BIT(bank); + } + + rww->used_banks |= used_banks; + rww->ongoing_io = true; + rww->ongoing_rd = true; + started = true; + +busy: + mutex_unlock(&nor->lock); + return started; +} + +static void spi_nor_rww_end_rd(struct spi_nor *nor, loff_t start, size_t len) +{ + struct spi_nor_rww *rww = &nor->rww; + u8 first, last; + int bank; + + mutex_lock(&nor->lock); + + spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last); + for (bank = first; bank <= last; bank++) + nor->rww.used_banks &= ~BIT(bank); + + rww->ongoing_io = false; + rww->ongoing_rd = false; + + mutex_unlock(&nor->lock); +} + static int spi_nor_prep_and_lock_rd(struct spi_nor *nor, loff_t start, size_t len) { int ret; @@ -1137,14 +1401,23 @@ static int spi_nor_prep_and_lock_rd(struct spi_nor *nor, loff_t start, size_t le if (ret) return ret; - mutex_lock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) + mutex_lock(&nor->lock); + else + ret = wait_event_killable(nor->rww.wait, + spi_nor_rww_start_rd(nor, start, len)); - return 0; + return ret; } static void spi_nor_unlock_and_unprep_rd(struct spi_nor *nor, loff_t start, size_t len) { - mutex_unlock(&nor->lock); + if (!spi_nor_use_parallel_locking(nor)) { + mutex_unlock(&nor->lock); + } else { + spi_nor_rww_end_rd(nor, start, len); + wake_up(&nor->rww.wait); + } spi_nor_unprep(nor); } @@ -1453,11 +1726,18 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len) dev_vdbg(nor->dev, "erase_cmd->size = 0x%08x, erase_cmd->opcode = 0x%02x, erase_cmd->count = %u\n", cmd->size, cmd->opcode, cmd->count); - ret = spi_nor_write_enable(nor); + ret = spi_nor_lock_device(nor); if (ret) goto destroy_erase_cmd_list; + ret = spi_nor_write_enable(nor); + if (ret) { + spi_nor_unlock_device(nor); + goto destroy_erase_cmd_list; + } + ret = spi_nor_erase_sector(nor, addr); + spi_nor_unlock_device(nor); if (ret) goto destroy_erase_cmd_list; @@ -1510,11 +1790,18 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { unsigned long timeout; - ret = spi_nor_write_enable(nor); + ret = spi_nor_lock_device(nor); if (ret) goto erase_err; + ret = spi_nor_write_enable(nor); + if (ret) { + spi_nor_unlock_device(nor); + goto erase_err; + } + ret = spi_nor_erase_chip(nor); + spi_nor_unlock_device(nor); if (ret) goto erase_err; @@ -1539,11 +1826,18 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) /* "sector"-at-a-time erase */ } else if (spi_nor_has_uniform_erase(nor)) { while (len) { - ret = spi_nor_write_enable(nor); + ret = spi_nor_lock_device(nor); if (ret) goto erase_err; + ret = spi_nor_write_enable(nor); + if (ret) { + spi_nor_unlock_device(nor); + goto erase_err; + } + ret = spi_nor_erase_sector(nor, addr); + spi_nor_unlock_device(nor); if (ret) goto erase_err; @@ -1836,11 +2130,18 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, addr = spi_nor_convert_addr(nor, addr); - ret = spi_nor_write_enable(nor); + ret = spi_nor_lock_device(nor); if (ret) goto write_err; + ret = spi_nor_write_enable(nor); + if (ret) { + spi_nor_unlock_device(nor); + goto write_err; + } + ret = spi_nor_write_data(nor, addr, page_remain, buf + i); + spi_nor_unlock_device(nor); if (ret < 0) goto write_err; written = ret; @@ -2531,7 +2832,8 @@ static void spi_nor_init_flags(struct spi_nor *nor) if (flags & NO_CHIP_ERASE) nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; - if (flags & SPI_NOR_RWW) + if (flags & SPI_NOR_RWW && nor->info->n_banks > 1 && + !nor->controller_ops) nor->flags |= SNOR_F_RWW; } @@ -3128,6 +3430,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (ret) return ret; + if (spi_nor_use_parallel_locking(nor)) + init_waitqueue_head(&nor->rww.wait); + /* * Configure the SPI memory: * - select op codes for (Fast) Read, Page Program and Sector Erase. diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index a3f8cdca90c8..82547b4b3708 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -343,6 +343,12 @@ struct spi_nor_flash_parameter; * struct spi_nor - Structure for defining the SPI NOR layer * @mtd: an mtd_info structure * @lock: the lock for the read/write/erase/lock/unlock operations + * @rww: Read-While-Write (RWW) sync lock + * @rww.wait: wait queue for the RWW sync + * @rww.ongoing_io: the bus is busy + * @rww.ongoing_rd: a read is ongoing on the chip + * @rww.ongoing_pe: a program/erase is ongoing on the chip + * @rww.used_banks: bitmap of the banks in use * @dev: pointer to an SPI device or an SPI NOR controller device * @spimem: pointer to the SPI memory device * @bouncebuf: bounce buffer used when the buffer passed by the MTD @@ -376,6 +382,13 @@ struct spi_nor_flash_parameter; struct spi_nor { struct mtd_info mtd; struct mutex lock; + struct spi_nor_rww { + wait_queue_head_t wait; + bool ongoing_io; + bool ongoing_rd; + bool ongoing_pe; + unsigned int used_banks; + } rww; struct device *dev; struct spi_mem *spimem; u8 *bouncebuf; From patchwork Tue Mar 28 15:41:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13191315 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EC401C761AF for ; Tue, 28 Mar 2023 15:43:18 +0000 (UTC) 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=4IyPyZ3ACCZXxZKHGWHRRifUPAUkt1t7nP4KCqmjsHc=; b=0cKdJYG2Hx24f2 20lKgbqd1TScqBFugBSnRyeJc2/ZOOhOiGJUAvrqR9gxfiLFmq4qx+yeJRaRxGdja1LcJI4JwB5qI PQqX7LR+AIvDOyMxRcCezAGZrllKeCTwp4OxGiaIhSTb/ELap8NAYHdDy4s1F4kVWbChymAUzZiyb iqmgaGWQf4o41LpHOhb00yuU11v+0u215TW1gUMkneTEfJb1eHLF3PTEuGQeEKLpQlgcZp68ICcXR D0+nEqJ+tliZnEvQdb1jDH1QdzvQoGpD3U04uh/X/NPRG9OtMhq5/mbgsaMv5qqvXioNPEdW4ol4A 3ItZCkJzf6eY6wlhtDBw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1phBSs-00EzWC-0Q; Tue, 28 Mar 2023 15:42:26 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1phBRt-00Eyk3-1D; Tue, 28 Mar 2023 15:41:26 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 1355960005; Tue, 28 Mar 2023 15:41:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1680018083; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9E7Cfw8PjSH7IBExwFg02Sat12AoGtk1zeyWxu1XsQM=; b=H7nan/xp7GAHMEJAzLszlQ/HTdCLS+hA+vOoSyBIaMrIy1j+Wr7wlpB6bhhX2KrHhr9orW qolnhuABusLammZDyeJjBdO05wbzlwaShWN2Y70k8glzVHn1GR3ySa9zM1qanUcUoylfY8 xU5c2NYuk/PXjoWNzLgVxG/4jygILL1ezuLsdL8M756nT8dQpUBlh3/lawcSQKOcma8UoK LYH5WXGOow2TtA8YnI8sU8SE9LRkiN6Rtqk7ylOjNWNT5OT3jPrJz53WBt8ajO6jOgJj1F 1gGMNrP2n+ltwMh9V7Ziqw/JQ6BjonEZhaZHdOuA1/MhROSYmZaNMXCY8/tUEg== From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Julien Su , Jaime Liao , Jaime Liao , Alvin Zhou , Thomas Petazzoni , Michal Simek , , Miquel Raynal Subject: [PATCH v5 8/8] mtd: spi-nor: macronix: Add support for mx25uw51245g with RWW Date: Tue, 28 Mar 2023 17:41:05 +0200 Message-Id: <20230328154105.448540-9-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230328154105.448540-1-miquel.raynal@bootlin.com> References: <20230328154105.448540-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230328_084125_718326_2B1D9FC5 X-CRM114-Status: GOOD ( 10.42 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Describe this new part and provide the RWW flag for it. There is no public datasheet, but here are the sfdp tables plus base testing to show it works. mx25uw51245g c2813a macronix 53464450080104fd00070114400000ff8701011c900000ff0a0001080001 00ff05000105200100ff84000102340100ff0000000000000000ffffffff ffffffffe5208affffffff1f00ff00ff00ff00ffeeffffffffff00ffffff 00ff0c2010d800ff00ff87790100821200e27704674630b030b0f4bdd55c 000000ff101000200000000000007ca14800000000008888000000000000 00400fd1fff30fd1fff300050090000500b1002b0095002b0096727103b8 727103b80000000090a3188200c069960000000000000000727100987271 00b8727100990000000072710098727100f872710099727100f900000000 00000000011501d0727106d8000086500000060100000000020001030002 00000000060100000000000072060002000000eec0697272717100d8f7f6 000a00001445988043060f0021dcffff 047a884cf44d9ffc2a94d3ab37b48c63 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp 6+0 records in 6+0 records out Copied 6291456 bytes from qspi_test to address 0x00000000 in flash Erased 6291456 bytes from address 0x00000000 in flash Copied 6291456 bytes from address 0x00000000 in flash to qspi_read 0000000 ffff ffff ffff ffff ffff ffff ffff ffff * 0600000 Copied 6291456 bytes from qspi_test to address 0x00000000 in flash Copied 6291456 bytes from address 0x00000000 in flash to qspi_read d24a9523db829a0df688f34b8dc76a1383b74024 qspi_test d24a9523db829a0df688f34b8dc76a1383b74024 qspi_read Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/macronix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 6853ec9ae65d..b65d41e5f749 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -82,6 +82,10 @@ static const struct flash_info macronix_nor_parts[] = { { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + { "mx25uw51245g", INFOB(0xc2813a, 0, 16 * 1024, 1024, 4) + PARSE_SFDP + FLAGS(SPI_NOR_RWW) + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, { "mx25v8035f", INFO(0xc22314, 0, 64 * 1024, 16) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },