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
1598 return stm_is_locked_sr(nor, ofs, len, status);1598 return stm_is_locked_sr(nor, ofs, len, status);
1599}1599}
1600 1600
1601static 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
1601static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)1607static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
1602{1608{
1603 struct spi_nor *nor = mtd_to_spi_nor(mtd);1609 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
1607 if (ret)1613 if (ret)
1608 return ret;1614 return ret;
1609 1615
1610 ret = nor->flash_lock(nor, ofs, len);1616 ret = nor->params.locking_ops->lock(nor, ofs, len);
1611 1617
1612 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);1618 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
1613 return ret;1619 return ret;
@@ -1622,7 +1628,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) · 8 unmodified lines
1622 if (ret)1628 if (ret)
1623 return ret;1629 return ret;
1624 1630
1625 ret = nor->flash_unlock(nor, ofs, len);1631 ret = nor->params.locking_ops->unlock(nor, ofs, len);
1626 1632
1627 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);1633 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
1628 return ret;1634 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
1637 if (ret)1643 if (ret)
1638 return ret;1644 return ret;
1639 1645
1640 ret = nor->flash_is_locked(nor, ofs, len);1646 ret = nor->params.locking_ops->is_locked(nor, ofs, len);
1641 1647
1642 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);1648 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
1643 return ret;1649 return ret;
@@ -4148,6 +4154,7 @@ static void macronix_set_default_init(struct spi_nor *nor) · 2504 unmodified lines
4148 4154
4149static void st_micron_set_default_init(struct spi_nor *nor)4155static void st_micron_set_default_init(struct spi_nor *nor)
4150{4156{
4157 nor->flags |= SNOR_F_HAS_LOCK;
4151 nor->params.quad_enable = NULL;4158 nor->params.quad_enable = NULL;
4152 nor->params.set_4byte = st_micron_set_4byte;4159 nor->params.set_4byte = st_micron_set_4byte;
4153}4160}
@@ -4291,6 +4298,23 @@ static void spi_nor_info_init_params(struct spi_nor *nor) · 137 unmodified lines
4291 spi_nor_init_uniform_erase_map(map, erase_mask, params->size);4298 spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
4292}4299}
4293 4300
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 */
4308static 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
4294/**4318/**
4295 * spi_nor_init_params() - Initialize the flash's parameters and settings.4319 * spi_nor_init_params() - Initialize the flash's parameters and settings.
4296 * @nor: pointer to a 'struct spi-nor'.4320 * @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
4316 * Please note that there is a ->post_bfpt() fixup hook that can overwrite4340 * Please note that there is a ->post_bfpt() fixup hook that can overwrite
4317 * the flash parameters and settings immediately after parsing the Basic4341 * the flash parameters and settings immediately after parsing the Basic
4318 * Flash Parameter Table.4342 * 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()
4319 */4347 */
4320static void spi_nor_init_params(struct spi_nor *nor)4348static void spi_nor_init_params(struct spi_nor *nor)
4321{4349{
@@ -4326,6 +4354,8 @@ static void spi_nor_init_params(struct spi_nor *nor) · 4 unmodified lines
4326 if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&4354 if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
4327 !(nor->info->flags & SPI_NOR_SKIP_SFDP))4355 !(nor->info->flags & SPI_NOR_SKIP_SFDP))
4328 spi_nor_sfdp_init_params(nor);4356 spi_nor_sfdp_init_params(nor);
4357
4358 spi_nor_late_init_params(nor);
4329}4359}
4330 4360
4331static int spi_nor_select_read(struct spi_nor *nor,4361static 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
4707 if (info->flags & SPI_S3AN)4737 if (info->flags & SPI_S3AN)
4708 nor->flags |= SNOR_F_READY_XSR_RDY;4738 nor->flags |= SNOR_F_READY_XSR_RDY;
4709 4739
4740 if (info->flags & SPI_NOR_HAS_LOCK)
4741 nor->flags |= SNOR_F_HAS_LOCK;
4742
4710 /*4743 /*
4711 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up4744 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
4712 * with the software protection bits set.4745 * with the software protection bits set.
@@ -4731,16 +4764,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, · 18 unmodified lines
4731 mtd->_read = spi_nor_read;4764 mtd->_read = spi_nor_read;
4732 mtd->_resume = spi_nor_resume;4765 mtd->_resume = spi_nor_resume;
4733 4766
4734 /* NOR protection support for STmicro/Micron chips and similar */4767 if (nor->params.locking_ops) {
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) {
4744 mtd->_lock = spi_nor_lock;4768 mtd->_lock = spi_nor_lock;
4745 mtd->_unlock = spi_nor_unlock;4769 mtd->_unlock = spi_nor_unlock;
4746 mtd->_is_locked = spi_nor_is_locked;4770 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
243 SNOR_F_BROKEN_RESET = BIT(6),243 SNOR_F_BROKEN_RESET = BIT(6),
244 SNOR_F_4B_OPCODES = BIT(7),244 SNOR_F_4B_OPCODES = BIT(7),
245 SNOR_F_HAS_4BAIT = BIT(8),245 SNOR_F_HAS_4BAIT = BIT(8),
246 SNOR_F_HAS_LOCK = BIT(9),
246};247};
247 248
248/**249/**
@@ -465,6 +466,18 @@ enum spi_nor_pp_command_index { · 216 unmodified lines
465/* Forward declaration that will be used in 'struct spi_nor_flash_parameter' */466/* Forward declaration that will be used in 'struct spi_nor_flash_parameter' */
466struct spi_nor;467struct spi_nor;
467 468
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 */
475struct 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
468/**481/**
469 * struct spi_nor_flash_parameter - SPI NOR flash parameters and settings.482 * struct spi_nor_flash_parameter - SPI NOR flash parameters and settings.
470 * Includes legacy flash parameters and settings that can be overwritten483 * Includes legacy flash parameters and settings that can be overwritten
@@ -483,6 +496,7 @@ struct spi_nor; · 12 unmodified lines
483 * Table.496 * Table.
484 * @quad_enable: enables SPI NOR quad mode.497 * @quad_enable: enables SPI NOR quad mode.
485 * @set_4byte: puts the SPI NOR in 4 byte addressing mode.498 * @set_4byte: puts the SPI NOR in 4 byte addressing mode.
499 * @locking_ops: SPI NOR locking methods.
486 */500 */
487struct spi_nor_flash_parameter {501struct spi_nor_flash_parameter {
488 u64 size;502 u64 size;
@@ -496,6 +510,8 @@ struct spi_nor_flash_parameter { · 7 unmodified lines
496 510
497 int (*quad_enable)(struct spi_nor *nor);511 int (*quad_enable)(struct spi_nor *nor);
498 int (*set_4byte)(struct spi_nor *nor, bool enable);512 int (*set_4byte)(struct spi_nor *nor, bool enable);
513
514 const struct spi_nor_locking_ops *locking_ops;
499};515};
500 516
501/**517/**
@@ -536,10 +552,6 @@ struct flash_info; · 34 unmodified lines
536 * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR552 * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
537 * at the offset @offs; if not provided by the driver,553 * at the offset @offs; if not provided by the driver,
538 * spi-nor will send the erase opcode via write_reg()554 * 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
543 * @clear_sr_bp: [FLASH-SPECIFIC] clears the Block Protection Bits from555 * @clear_sr_bp: [FLASH-SPECIFIC] clears the Block Protection Bits from
544 * the SPI NOR Status Register.556 * the SPI NOR Status Register.
545 * @params: [FLASH-SPECIFIC] SPI-NOR flash parameters and settings.557 * @params: [FLASH-SPECIFIC] SPI-NOR flash parameters and settings.
@@ -579,9 +591,6 @@ struct spi_nor { · 33 unmodified lines
579 size_t len, const u_char *write_buf);591 size_t len, const u_char *write_buf);
580 int (*erase)(struct spi_nor *nor, loff_t offs);592 int (*erase)(struct spi_nor *nor, loff_t offs);
581 593
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);
585 int (*clear_sr_bp)(struct spi_nor *nor);594 int (*clear_sr_bp)(struct spi_nor *nor);
586 struct spi_nor_flash_parameter params;595 struct spi_nor_flash_parameter params;
587 596

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