case ECCGETLAYOUT:
case ECCGETSTATS:
case MTDFILEMODE:
@@ -938,6 +939,7 @@ static int mtdchar_ioctl(struct file *file, u_int
cmd, u_long arg)
}
case OTPLOCK:
+ case OTPERASE:
{
struct otp_info oinfo;
@@ -945,7 +947,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 2d6423d89a17..d844d718ef77 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1918,6 +1918,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)
{
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 157357ec1441..734ad7a8c353 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -336,6 +336,8 @@ struct mtd_info {
size_t len, size_t *retlen, u_char *buf);
int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
size_t len);
+ int (*_erase_user_prot_reg) (struct mtd_info *mtd, loff_t from,
+ size_t len);
int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
void (*_sync) (struct mtd_info *mtd);
@@ -517,6 +519,7 @@ int mtd_read_user_prot_reg(struct mtd_info *mtd,
loff_t from, size_t len,
int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t
len,
size_t *retlen, u_char *buf);
int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t
len);
+int mtd_erase_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t
len);
int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index 65b9db936557..242015f60d10 100644
--- a/include/uapi/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
@@ -205,6 +205,8 @@ struct otp_info {
* without OOB, e.g., NOR flash.
*/
#define MEMWRITE _IOWR('M', 24, struct mtd_write_req)
+/* Erase a given range of user data (must be in mode
%MTD_FILE_MODE_OTP_USER) */
+#define OTPERASE _IOR('M', 25, struct otp_info)