From 1bd90ff5a11fdb79eb865173d2bf4b5e25d95679 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 19 Apr 2012 20:12:56 +0200 Subject: mtd: implement mtd_lock and mtd_unlock Needed for NOR flashes. Signed-off-by: Sascha Hauer --- drivers/mtd/core.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index e852fb6b4..4ddf9d1bc 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -95,6 +95,20 @@ static int mtd_op_erase(struct cdev *cdev, size_t count, loff_t offset) return 0; } + +static ssize_t mtd_op_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) +{ + struct mtd_info *mtd = cdev->priv; + + if (!mtd->unlock || !mtd->lock) + return -ENOSYS; + + if (prot) + return mtd_lock(mtd, offset, count); + else + return mtd_unlock(mtd, offset, count); +} + #endif /* CONFIG_MTD_WRITE */ int mtd_ioctl(struct cdev *cdev, int request, void *buf) @@ -161,6 +175,28 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) return ret; } +int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->lock) + return -EOPNOTSUPP; + if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + return -EINVAL; + if (!len) + return 0; + return mtd->lock(mtd, ofs, len); +} + +int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->unlock) + return -EOPNOTSUPP; + if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + return -EINVAL; + if (!len) + return 0; + return mtd->unlock(mtd, ofs, len); +} + int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->block_isbad) @@ -206,6 +242,7 @@ static struct file_operations mtd_ops = { #ifdef CONFIG_MTD_WRITE .write = mtd_op_write, .erase = mtd_op_erase, + .protect = mtd_op_protect, #endif .ioctl = mtd_ioctl, .lseek = dev_lseek_default, diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index c1760de10..3892bed0f 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -257,6 +257,8 @@ static inline void mtd_erase_callback(struct erase_info *instr) } #endif +int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); -- cgit v1.2.3