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.
Unified · Split
| @@ -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 | ||
| 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 | |||
| 1601 | static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 1607 | static 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 | ||
| 4149 | static void st_micron_set_default_init(struct spi_nor *nor) | 4155 | static 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 | */ | ||
| 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 | |||
| 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 overwrite | 4340 | * Please note that there is a ->post_bfpt() fixup hook that can overwrite |
| 4317 | * the flash parameters and settings immediately after parsing the Basic | 4341 | * 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 | */ |
| 4320 | static void spi_nor_init_params(struct spi_nor *nor) | 4348 | static 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 | ||
| 4331 | static int spi_nor_select_read(struct spi_nor *nor, | 4361 | 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 | |||
| 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 up | 4744 | * 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; |
| @@ -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' */ |
| 466 | struct spi_nor; | 467 | struct 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 | */ | ||
| 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 | |||
| 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 overwritten | 483 | * 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 | */ |
| 487 | struct spi_nor_flash_parameter { | 501 | struct 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 NOR | 552 | * @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 from | 555 | * @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 | ||