Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: spi-nor: factor out replace-able flash_{lock,unlock}

Flash lock/unlock is a flash-specific operations. Factor out a callback
for it to more readily support other vendors.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Tested-by: VIET NGA DAO <vndao@altera.com>

+43 -19
+38 -19
drivers/mtd/spi-nor/spi-nor.c
··· 369 369 return ret; 370 370 } 371 371 372 - static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 372 + static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) 373 373 { 374 - struct spi_nor *nor = mtd_to_spi_nor(mtd); 374 + struct mtd_info *mtd = nor->mtd; 375 375 uint32_t offset = ofs; 376 376 uint8_t status_old, status_new; 377 377 int ret = 0; 378 - 379 - ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); 380 - if (ret) 381 - return ret; 382 378 383 379 status_old = read_sr(nor); 384 380 ··· 398 402 (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) { 399 403 write_enable(nor); 400 404 ret = write_sr(nor, status_new); 401 - if (ret) 402 - goto err; 403 405 } 404 406 405 - err: 406 - spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); 407 407 return ret; 408 408 } 409 409 410 - static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 410 + static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) 411 411 { 412 - struct spi_nor *nor = mtd_to_spi_nor(mtd); 412 + struct mtd_info *mtd = nor->mtd; 413 413 uint32_t offset = ofs; 414 414 uint8_t status_old, status_new; 415 415 int ret = 0; 416 - 417 - ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); 418 - if (ret) 419 - return ret; 420 416 421 417 status_old = read_sr(nor); 422 418 ··· 432 444 (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) { 433 445 write_enable(nor); 434 446 ret = write_sr(nor, status_new); 435 - if (ret) 436 - goto err; 437 447 } 438 448 439 - err: 449 + return ret; 450 + } 451 + 452 + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 453 + { 454 + struct spi_nor *nor = mtd_to_spi_nor(mtd); 455 + int ret; 456 + 457 + ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); 458 + if (ret) 459 + return ret; 460 + 461 + ret = nor->flash_lock(nor, ofs, len); 462 + 440 463 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); 464 + return ret; 465 + } 466 + 467 + static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 468 + { 469 + struct spi_nor *nor = mtd_to_spi_nor(mtd); 470 + int ret; 471 + 472 + ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); 473 + if (ret) 474 + return ret; 475 + 476 + ret = nor->flash_unlock(nor, ofs, len); 477 + 478 + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); 441 479 return ret; 442 480 } 443 481 ··· 1059 1045 1060 1046 /* nor protection support for STmicro chips */ 1061 1047 if (JEDEC_MFR(info) == CFI_MFR_ST) { 1048 + nor->flash_lock = stm_lock; 1049 + nor->flash_unlock = stm_unlock; 1050 + } 1051 + 1052 + if (nor->flash_lock && nor->flash_unlock) { 1062 1053 mtd->_lock = spi_nor_lock; 1063 1054 mtd->_unlock = spi_nor_unlock; 1064 1055 }
+5
include/linux/mtd/spi-nor.h
··· 155 155 * @write: [DRIVER-SPECIFIC] write data to the SPI NOR 156 156 * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR 157 157 * at the offset @offs 158 + * @lock: [FLASH-SPECIFIC] lock a region of the SPI NOR 159 + * @unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR 158 160 * @priv: the private data 159 161 */ 160 162 struct spi_nor { ··· 190 188 void (*write)(struct spi_nor *nor, loff_t to, 191 189 size_t len, size_t *retlen, const u_char *write_buf); 192 190 int (*erase)(struct spi_nor *nor, loff_t offs); 191 + 192 + int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); 193 + int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); 193 194 194 195 void *priv; 195 196 };