History

mtd: spi-nor: Rework the SPI NOR lock/unlock logic

Add the SNOR_F_HAS_LOCK flag and set it when SPI_NOR_HAS_LOCK is set in the flash_info entry or when it's a Micron or ST flash. Move the locking hooks in a separate struct so that we have just one field to update when we change the locking implementation.

Boris Brezillon committed 7 years ago

Commit dff97241 parent 64c160f2 files · +53 −20Browse files

Unified · Split

2 files
  1. drivers/mtd/spi-nor/spi-nor.c +37 −13
  2. include/linux/mtd/spi-nor.h +16 −7
drivers/mtd/spi-nor/spi-nor.c+37−13
@@ -1598,6 +1598,12 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) · 1597 unmodified lines
15981598 return stm_is_locked_sr(nor, ofs, len, status);
15991599 }
16001600
1601+static const struct spi_nor_locking_ops stm_locking_ops = {
1602+ .lock = stm_lock,
1603+ .unlock = stm_unlock,
1604+ .is_locked = stm_is_locked,
1605+};
1606+
16011607 static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16021608 {
16031609 struct spi_nor *nor = mtd_to_spi_nor(mtd);
@@ -1607,7 +1613,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 3 unmodified lines
16071613 if (ret)
16081614 return ret;
16091615
1610− ret = nor->flash_lock(nor, ofs, len);
1616+ ret = nor->params.locking_ops->lock(nor, ofs, len);
16111617
16121618 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
16131619 return ret;
@@ -1622,7 +1628,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 8 unmodified lines
16221628 if (ret)
16231629 return ret;
16241630
1625− ret = nor->flash_unlock(nor, ofs, len);
1631+ ret = nor->params.locking_ops->unlock(nor, ofs, len);
16261632
16271633 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
16281634 return ret;
@@ -1637,7 +1643,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 8 unmodified lines
16371643 if (ret)
16381644 return ret;
16391645
1640− ret = nor->flash_is_locked(nor, ofs, len);
1646+ ret = nor->params.locking_ops->is_locked(nor, ofs, len);
16411647
16421648 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
16431649 return ret;
@@ -4148,6 +4154,7 @@ static void macronix_set_default_init(struct spi_nor *nor) · 2504 unmodified lines
41484154
41494155 static void st_micron_set_default_init(struct spi_nor *nor)
41504156 {
4157+ nor->flags |= SNOR_F_HAS_LOCK;
41514158 nor->params.quad_enable = NULL;
41524159 nor->params.set_4byte = st_micron_set_4byte;
41534160 }
@@ -4291,6 +4298,23 @@ static void spi_nor_info_init_params(struct spi_nor *nor) · 137 unmodified lines
42914298 spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
42924299 }
42934300
4301+/**
4302+ * spi_nor_late_init_params() - Late initialization of default flash parameters.
4303+ * @nor: pointer to a 'struct spi_nor'
4304+ *
4305+ * Used to set default flash parameters and settings when the ->default_init()
4306+ * hook or the SFDP parser let voids.
4307+ */
4308+static void spi_nor_late_init_params(struct spi_nor *nor)
4309+{
4310+ /*
4311+ * NOR protection support. When locking_ops are not provided, we pick
4312+ * the default ones.
4313+ */
4314+ if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops)
4315+ nor->params.locking_ops = &stm_locking_ops;
4316+}
4317+
42944318 /**
42954319 * spi_nor_init_params() - Initialize the flash's parameters and settings.
42964320 * @nor: pointer to a 'struct spi-nor'.
@@ -4316,6 +4340,10 @@ static void spi_nor_info_init_params(struct spi_nor *nor) · 19 unmodified lines
43164340 * Please note that there is a ->post_bfpt() fixup hook that can overwrite
43174341 * the flash parameters and settings immediately after parsing the Basic
43184342 * Flash Parameter Table.
4343+ *
4344+ * 4/ Late default flash parameters initialization, used when the
4345+ * ->default_init() hook or the SFDP parser do not set specific params.
4346+ * spi_nor_late_init_params()
43194347 */
43204348 static void spi_nor_init_params(struct spi_nor *nor)
43214349 {
@@ -4326,6 +4354,8 @@ static void spi_nor_init_params(struct spi_nor *nor) · 4 unmodified lines
43264354 if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
43274355 !(nor->info->flags & SPI_NOR_SKIP_SFDP))
43284356 spi_nor_sfdp_init_params(nor);
4357+
4358+ spi_nor_late_init_params(nor);
43294359 }
43304360
43314361 static int spi_nor_select_read(struct spi_nor *nor,
@@ -4707,6 +4737,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, · 375 unmodified lines
47074737 if (info->flags & SPI_S3AN)
47084738 nor->flags |= SNOR_F_READY_XSR_RDY;
47094739
4740+ if (info->flags & SPI_NOR_HAS_LOCK)
4741+ nor->flags |= SNOR_F_HAS_LOCK;
4742+
47104743 /*
47114744 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
47124745 * with the software protection bits set.
@@ -4731,16 +4764,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, · 18 unmodified lines
47314764 mtd->_read = spi_nor_read;
47324765 mtd->_resume = spi_nor_resume;
47334766
4734− /* NOR protection support for STmicro/Micron chips and similar */
4735− if (JEDEC_MFR(info) == SNOR_MFR_ST ||
4736− JEDEC_MFR(info) == SNOR_MFR_MICRON ||
4737− info->flags & SPI_NOR_HAS_LOCK) {
4738− nor->flash_lock = stm_lock;
4739− nor->flash_unlock = stm_unlock;
4740− nor->flash_is_locked = stm_is_locked;
4741− }
4742−
4743− if (nor->flash_lock && nor->flash_unlock && nor->flash_is_locked) {
4767+ if (nor->params.locking_ops) {
47444768 mtd->_lock = spi_nor_lock;
47454769 mtd->_unlock = spi_nor_unlock;
47464770 mtd->_is_locked = spi_nor_is_locked;
include/linux/mtd/spi-nor.h+16−7
@@ -243,6 +243,7 @@ enum spi_nor_option_flags { · 242 unmodified lines
243243 SNOR_F_BROKEN_RESET = BIT(6),
244244 SNOR_F_4B_OPCODES = BIT(7),
245245 SNOR_F_HAS_4BAIT = BIT(8),
246+ SNOR_F_HAS_LOCK = BIT(9),
246247 };
247248
248249 /**
@@ -465,6 +466,18 @@ enum spi_nor_pp_command_index { · 216 unmodified lines
465466 /* Forward declaration that will be used in 'struct spi_nor_flash_parameter' */
466467 struct spi_nor;
467468
469+/**
470+ * struct spi_nor_locking_ops - SPI NOR locking methods
471+ * @lock: lock a region of the SPI NOR.
472+ * @unlock: unlock a region of the SPI NOR.
473+ * @is_locked: check if a region of the SPI NOR is completely locked
474+ */
475+struct spi_nor_locking_ops {
476+ int (*lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
477+ int (*unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
478+ int (*is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
479+};
480+
468481 /**
469482 * struct spi_nor_flash_parameter - SPI NOR flash parameters and settings.
470483 * Includes legacy flash parameters and settings that can be overwritten
@@ -483,6 +496,7 @@ struct spi_nor; · 12 unmodified lines
483496 * Table.
484497 * @quad_enable: enables SPI NOR quad mode.
485498 * @set_4byte: puts the SPI NOR in 4 byte addressing mode.
499+ * @locking_ops: SPI NOR locking methods.
486500 */
487501 struct spi_nor_flash_parameter {
488502 u64 size;
@@ -496,6 +510,8 @@ struct spi_nor_flash_parameter { · 7 unmodified lines
496510
497511 int (*quad_enable)(struct spi_nor *nor);
498512 int (*set_4byte)(struct spi_nor *nor, bool enable);
513+
514+ const struct spi_nor_locking_ops *locking_ops;
499515 };
500516
501517 /**
@@ -536,10 +552,6 @@ struct flash_info; · 34 unmodified lines
536552 * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
537553 * at the offset @offs; if not provided by the driver,
538554 * spi-nor will send the erase opcode via write_reg()
539− * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR
540− * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR
541− * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is
542− * completely locked
543555 * @clear_sr_bp: [FLASH-SPECIFIC] clears the Block Protection Bits from
544556 * the SPI NOR Status Register.
545557 * @params: [FLASH-SPECIFIC] SPI-NOR flash parameters and settings.
@@ -579,9 +591,6 @@ struct spi_nor { · 33 unmodified lines
579591 size_t len, const u_char *write_buf);
580592 int (*erase)(struct spi_nor *nor, loff_t offs);
581593
582− int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
583− int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
584− int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
585594 int (*clear_sr_bp)(struct spi_nor *nor);
586595 struct spi_nor_flash_parameter params;
587596

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t