mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
mtd: spi-nor: swp: Simplify checking the locked/unlocked range
In both the locking/unlocking steps, at the end we verify whether we do not lock/unlock more than requested (in which case an error must be returned). While being possible to do that with very simple mask comparisons, it does not scale when adding extra locking features such as the CMP possibility. In order to make these checks slightly easier to read and more future proof, use existing helpers to read the (future) status register, extract the covered range, and compare it with very usual algebric comparisons. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
This commit is contained in:
parent
290e838336
commit
c672673c4b
|
|
@ -200,7 +200,8 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
|
|||
u64 min_prot_len;
|
||||
int ret;
|
||||
u8 status_old[1] = {}, status_new[1] = {};
|
||||
u8 bp_mask = spi_nor_get_sr_bp_mask(nor);
|
||||
loff_t ofs_old, ofs_new;
|
||||
u64 len_old, len_new;
|
||||
loff_t lock_len;
|
||||
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
|
||||
bool use_top;
|
||||
|
|
@ -248,10 +249,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Don't "lock" with no region! */
|
||||
if (!(status_new[0] & bp_mask))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Disallow further writes if WP# pin is neither left floating nor
|
||||
* wrongly tied to GND (that includes internal pull-downs).
|
||||
|
|
@ -260,12 +257,20 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
|
|||
if (!(nor->flags & SNOR_F_NO_WP))
|
||||
status_new[0] |= SR_SRWD;
|
||||
|
||||
spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old);
|
||||
spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new);
|
||||
|
||||
/* Don't "lock" with no region! */
|
||||
if (!len_new)
|
||||
return -EINVAL;
|
||||
|
||||
/* Don't bother if they're the same */
|
||||
if (status_new[0] == status_old[0])
|
||||
return 0;
|
||||
|
||||
/* Only modify protection if it will not unlock other areas */
|
||||
if ((status_new[0] & bp_mask) < (status_old[0] & bp_mask))
|
||||
if (len_old &&
|
||||
(ofs_old < ofs_new || (ofs_new + len_new) < (ofs_old + len_old)))
|
||||
return -EINVAL;
|
||||
|
||||
return spi_nor_write_sr_and_check(nor, status_new[0]);
|
||||
|
|
@ -281,7 +286,8 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
|
|||
u64 min_prot_len;
|
||||
int ret;
|
||||
u8 status_old[1], status_new[1];
|
||||
u8 bp_mask = spi_nor_get_sr_bp_mask(nor);
|
||||
loff_t ofs_old, ofs_new;
|
||||
u64 len_old, len_new;
|
||||
loff_t lock_len;
|
||||
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
|
||||
bool use_top;
|
||||
|
|
@ -346,7 +352,10 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
|
|||
return 0;
|
||||
|
||||
/* Only modify protection if it will not lock other areas */
|
||||
if ((status_new[0] & bp_mask) > (status_old[0] & bp_mask))
|
||||
spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old);
|
||||
spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new);
|
||||
if (len_old && len_new &&
|
||||
(ofs_new < ofs_old || (ofs_old + len_old) < (ofs_new + len_new)))
|
||||
return -EINVAL;
|
||||
|
||||
return spi_nor_write_sr_and_check(nor, status_new[0]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user