[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-8-487bc7129931@bootlin.com>
Date: Fri, 14 Nov 2025 18:53:09 +0100
From: Miquel Raynal <miquel.raynal@...tlin.com>
To: Tudor Ambarus <tudor.ambarus@...aro.org>,
Pratyush Yadav <pratyush@...nel.org>, Michael Walle <mwalle@...nel.org>,
Richard Weinberger <richard@....at>, Vignesh Raghavendra <vigneshr@...com>,
Jonathan Corbet <corbet@....net>
Cc: Sean Anderson <sean.anderson@...ux.dev>,
Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
Steam Lin <STLin2@...bond.com>, linux-mtd@...ts.infradead.org,
linux-kernel@...r.kernel.org, linux-doc@...r.kernel.org,
Miquel Raynal <miquel.raynal@...tlin.com>
Subject: [PATCH 08/19] mtd: spi-nor: swp: Use a pointer for SR instead of a
single byte
At this stage, the Status Register is most often seen as a single
byte. This is subject to change when we will need to read the CMP bit
which is located in the Control Register (kind of secondary status
register). Both will need to be carried.
Change a few prototypes to carry a u8 pointer. This way it also makes it
very clear where we access the first register, and where we will access
the second.
There is no functional change.
Signed-off-by: Miquel Raynal <miquel.raynal@...tlin.com>
---
drivers/mtd/spi-nor/swp.c | 48 ++++++++++++++++++++++++-----------------------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
index 350fb8cd67dbafa3c62201c8c06bff7131143c04..bac07287ada036f49c25237549e4900f76a0247d 100644
--- a/drivers/mtd/spi-nor/swp.c
+++ b/drivers/mtd/spi-nor/swp.c
@@ -53,13 +53,13 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
return sector_size;
}
-static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
+static void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs,
u64 *len)
{
u64 min_prot_len;
u8 mask = spi_nor_get_sr_bp_mask(nor);
u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
- u8 bp, val = sr & mask;
+ u8 bp, val = sr[0] & mask;
if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6)
val = (val & ~SR_BP3_BIT6) | SR_BP3;
@@ -79,7 +79,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
if (*len > nor->params->size)
*len = nor->params->size;
- if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
+ if (nor->flags & SNOR_F_HAS_SR_TB && sr[0] & tb_mask)
*ofs = 0;
else
*ofs = nor->params->size - *len;
@@ -90,7 +90,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
* (if @locked is false); false otherwise.
*/
static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs,
- u64 len, u8 sr, bool locked)
+ u64 len, const u8 *sr, bool locked)
{
loff_t lock_offs, lock_offs_max, offs_max;
u64 lock_len;
@@ -111,13 +111,13 @@ static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs,
return (ofs >= lock_offs_max) || (offs_max <= lock_offs);
}
-static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, u8 sr)
+static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr)
{
return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true);
}
static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len,
- u8 sr)
+ const u8 *sr)
{
return spi_nor_check_lock_status_sr(nor, ofs, len, sr, false);
}
@@ -158,7 +158,8 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len,
static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
{
u64 min_prot_len;
- int ret, status_old, status_new;
+ int ret;
+ u8 status_old[1] = {}, status_new[1] = {};
u8 mask = spi_nor_get_sr_bp_mask(nor);
u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
u8 pow, val;
@@ -170,7 +171,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
if (ret)
return ret;
- status_old = nor->bouncebuf[0];
+ status_old[0] = nor->bouncebuf[0];
/* If nothing in our range is unlocked, we don't need to do anything */
if (spi_nor_is_locked_sr(nor, ofs, len, status_old))
@@ -215,7 +216,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
return -EINVAL;
}
- status_new = (status_old & ~mask & ~tb_mask) | val;
+ status_new[0] = (status_old[0] & ~mask & ~tb_mask) | val;
/*
* Disallow further writes if WP# pin is neither left floating nor
@@ -223,20 +224,20 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
* WP# pin hard strapped to GND can be a valid use case.
*/
if (!(nor->flags & SNOR_F_NO_WP))
- status_new |= SR_SRWD;
+ status_new[0] |= SR_SRWD;
if (!use_top)
- status_new |= tb_mask;
+ status_new[0] |= tb_mask;
/* Don't bother if they're the same */
- if (status_new == status_old)
+ if (status_new[0] == status_old[0])
return 0;
/* Only modify protection if it will not unlock other areas */
- if ((status_new & mask) < (status_old & mask))
+ if ((status_new[0] & mask) < (status_old[0] & mask))
return -EINVAL;
- return spi_nor_write_sr_and_check(nor, status_new);
+ return spi_nor_write_sr_and_check(nor, status_new[0]);
}
/*
@@ -247,7 +248,8 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
{
u64 min_prot_len;
- int ret, status_old, status_new;
+ int ret;
+ u8 status_old[1], status_new[1];
u8 mask = spi_nor_get_sr_bp_mask(nor);
u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
u8 pow, val;
@@ -259,7 +261,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
if (ret)
return ret;
- status_old = nor->bouncebuf[0];
+ status_old[0] = nor->bouncebuf[0];
/* If nothing in our range is locked, we don't need to do anything */
if (spi_nor_is_unlocked_sr(nor, ofs, len, status_old))
@@ -303,24 +305,24 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
return -EINVAL;
}
- status_new = (status_old & ~mask & ~tb_mask) | val;
+ status_new[0] = (status_old[0] & ~mask & ~tb_mask) | val;
/* Don't protect status register if we're fully unlocked */
if (lock_len == 0)
- status_new &= ~SR_SRWD;
+ status_new[0] &= ~SR_SRWD;
if (!use_top)
- status_new |= tb_mask;
+ status_new[0] |= tb_mask;
/* Don't bother if they're the same */
- if (status_new == status_old)
+ if (status_new[0] == status_old[0])
return 0;
/* Only modify protection if it will not lock other areas */
- if ((status_new & mask) > (status_old & mask))
+ if ((status_new[0] & mask) > (status_old[0] & mask))
return -EINVAL;
- return spi_nor_write_sr_and_check(nor, status_new);
+ return spi_nor_write_sr_and_check(nor, status_new[0]);
}
/*
@@ -338,7 +340,7 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, loff_t ofs, u64 len)
if (ret)
return ret;
- return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]);
+ return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf);
}
/*
--
2.51.0
Powered by blists - more mailing lists