summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMichael Walle <michael@walle.cc>2021-03-03 21:18:19 +0100
committerMiquel Raynal <miquel.raynal@bootlin.com>2021-03-28 19:24:54 +0200
commite3c1f1c92d6ede3cfa09d6a103d3d1c1ef645e35 (patch)
tree3349a378304c85ffac78c3c2de03c6824ba23c95 /drivers/mtd
parent1e97743fd180981bef5f01402342bb54bf1c6366 (diff)
downloadlinux-e3c1f1c92d6ede3cfa09d6a103d3d1c1ef645e35.tar.bz2
mtd: add OTP (one-time-programmable) erase ioctl
This may sound like a contradiction but some SPI-NOR flashes really support erasing their OTP region until it is finally locked. Having the possibility to erase an OTP region might come in handy during development. The ioctl argument follows the OTPLOCK style. Signed-off-by: Michael Walle <michael@walle.cc> Acked-by: Vignesh Raghavendra <vigneshr@ti.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20210303201819.2752-1-michael@walle.cc
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/mtdchar.c7
-rw-r--r--drivers/mtd/mtdcore.c12
2 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 870f7a19ad9d..155e991d9d75 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -666,6 +666,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
case MEMWRITEOOB64:
case MEMWRITE:
case OTPLOCK:
+ case OTPERASE:
if (!(file->f_mode & FMODE_WRITE))
return -EPERM;
break;
@@ -930,6 +931,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
}
case OTPLOCK:
+ case OTPERASE:
{
struct otp_info oinfo;
@@ -937,7 +939,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
return -EINVAL;
if (copy_from_user(&oinfo, argp, sizeof(oinfo)))
return -EFAULT;
- ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
+ if (cmd == OTPLOCK)
+ ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
+ else
+ ret = mtd_erase_user_prot_reg(mtd, oinfo.start, oinfo.length);
break;
}
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 38782ceea1f6..aea58366a94e 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1919,6 +1919,18 @@ int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
}
EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
+int mtd_erase_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
+{
+ struct mtd_info *master = mtd_get_master(mtd);
+
+ if (!master->_erase_user_prot_reg)
+ return -EOPNOTSUPP;
+ if (!len)
+ return 0;
+ return master->_erase_user_prot_reg(master, from, len);
+}
+EXPORT_SYMBOL_GPL(mtd_erase_user_prot_reg);
+
/* Chip-supported device locking */
int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{