
sync the protect command from legacy cmd/sf.c and update them according to current spi-nor framework.
Signed-off-by: Suneel Garapati suneelglinux@gmail.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- cmd/spinor.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/mtd/mtd-uclass.c | 19 +++++++++++++++++++ include/mtd.h | 11 +++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/cmd/spinor.c b/cmd/spinor.c index b781151..ef8decf 100644 --- a/cmd/spinor.c +++ b/cmd/spinor.c @@ -151,6 +151,44 @@ static int do_spinor_write_read(int argc, char * const argv[]) return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE; }
+static int do_spinor_protect(int argc, char * const argv[]) +{ + struct mtd_info *mtd; + struct spi_nor *nor; + loff_t sector, len, maxsize; + char *endp; + int idx = 0; + bool prot = false; + int ret = CMD_RET_FAILURE; + + if (argc != 4) + return CMD_RET_USAGE; + + nor = init_spinor_device(curr_device, false); + if (!nor) + return CMD_RET_FAILURE; + + sector = simple_strtoul(argv[2], &endp, 16); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_FAILURE; + + mtd = spi_nor_get_mtd_info(nor); + if (mtd_arg_off_size(argc - 3, &argv[3], &idx, §or, &len, + &maxsize, MTD_DEV_TYPE_NOR, mtd->size)) + return CMD_RET_FAILURE; + + if (strcmp(argv[1], "lock") == 0) + prot = true; + else if (strcmp(argv[1], "unlock") == 0) + prot = false; + else + return -1; /* Unknown parameter */ + + ret = mtd_dprotect(mtd, sector, len, prot); + + return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE; +} + static int mtd_parse_len_arg(struct mtd_info *mtd, char *arg, loff_t *len) { char *ep; @@ -258,6 +296,11 @@ static int do_spinor(cmd_tbl_t *cmdtp, int flag, int argc, goto done; }
+ if (strcmp(cmd, "protect") == 0) { + ret = do_spinor_protect(argc, argv); + goto done; + } + done: if (ret != -1) return ret; @@ -272,7 +315,9 @@ static char spinor_help_text[] = "spinor dev [devnum] - show or set current spinor device\n" "spinor erase offset len - erase 'len' bytes from 'offset'\n" "spinor write addr to len - write 'len' bytes to 'to' from 'addr'\n" - "spinor read addr from len - read 'len' bytes from 'from' to 'addr'"; + "spinor read addr from len - read 'len' bytes from 'from' to 'addr'\n" + "spinor protect lock/unlock sector len - protect/unprotect 'len' bytes starting\n" + " at address 'sector'";
U_BOOT_CMD( spinor, 5, 1, do_spinor, diff --git a/drivers/mtd/mtd-uclass.c b/drivers/mtd/mtd-uclass.c index d9ecfea..535f68e 100644 --- a/drivers/mtd/mtd-uclass.c +++ b/drivers/mtd/mtd-uclass.c @@ -73,6 +73,25 @@ int mtd_dwrite(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, return ops->write(dev, to, len, retlen, buf); }
+int mtd_dprotect(struct mtd_info *mtd, loff_t ofs, uint64_t len, bool prot) +{ + struct udevice *dev = mtd->dev; + const struct mtd_ops *ops = mtd_get_ops(dev); + + if (!ops->lock || !ops->unlock) + return -ENOSYS; + + if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + return -EINVAL; + if (!len) + return 0; + + if (prot) + return ops->lock(dev, ofs, len); + else + return ops->unlock(dev, ofs, len); +} + int mtd_find_device(int mtd_if_type, int devnum, struct udevice **devp) { struct uclass *uc; diff --git a/include/mtd.h b/include/mtd.h index acb2256..6390133 100644 --- a/include/mtd.h +++ b/include/mtd.h @@ -61,6 +61,17 @@ int mtd_dwrite(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
/** + * mtd_dprotect - protect area of MTD device + * + * @mtd: MTD device + * @ofs: sector start offset into device in bytes to protect to + * @len: len of bytes to protect + * @prot: protect boolean, true for lock, false for unlock + * @return 0 if OK, -ve on error + */ +int mtd_dprotect(struct mtd_info *mtd, loff_t ofs, uint64_t len, bool prot); + +/** * mtd_derase() - erase blocks of the MTD device * * @mtd: MTD device