aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdchar.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-02-12 05:40:00 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-03-24 05:00:19 -0400
commit402d326519c1a4859c527702383f4e60f606ef52 (patch)
treebeb302d56d7671d372ae73f2664feed2a5b1226d /drivers/mtd/mtdchar.c
parent9ce969082e490d0a5a81862b364337c93dc3482a (diff)
NOMMU: Present backing device capabilities for MTD chardevs
Present backing device capabilities for MTD character device files to allow NOMMU mmap to do direct mapping where possible. Signed-off-by: David Howells <dhowells@redhat.com> Tested-by: Bernd Schmidt <bernd.schmidt@analog.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r--drivers/mtd/mtdchar.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 2c8a16f49ca2..f478f1fc3949 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,6 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/backing-dev.h>
16 17
17#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
18#include <linux/mtd/compatmac.h> 19#include <linux/mtd/compatmac.h>
@@ -107,12 +108,15 @@ static int mtd_open(struct inode *inode, struct file *file)
107 goto out; 108 goto out;
108 } 109 }
109 110
110 if (MTD_ABSENT == mtd->type) { 111 if (mtd->type == MTD_ABSENT) {
111 put_mtd_device(mtd); 112 put_mtd_device(mtd);
112 ret = -ENODEV; 113 ret = -ENODEV;
113 goto out; 114 goto out;
114 } 115 }
115 116
117 if (mtd->backing_dev_info)
118 file->f_mapping->backing_dev_info = mtd->backing_dev_info;
119
116 /* You can't open it RW if it's not a writeable device */ 120 /* You can't open it RW if it's not a writeable device */
117 if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { 121 if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
118 put_mtd_device(mtd); 122 put_mtd_device(mtd);
@@ -781,6 +785,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
781 return ret; 785 return ret;
782} /* memory_ioctl */ 786} /* memory_ioctl */
783 787
788/*
789 * try to determine where a shared mapping can be made
790 * - only supported for NOMMU at the moment (MMU can't doesn't copy private
791 * mappings)
792 */
793#ifndef CONFIG_MMU
794static unsigned long mtd_get_unmapped_area(struct file *file,
795 unsigned long addr,
796 unsigned long len,
797 unsigned long pgoff,
798 unsigned long flags)
799{
800 struct mtd_file_info *mfi = file->private_data;
801 struct mtd_info *mtd = mfi->mtd;
802
803 if (mtd->get_unmapped_area) {
804 unsigned long offset;
805
806 if (addr != 0)
807 return (unsigned long) -EINVAL;
808
809 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
810 return (unsigned long) -EINVAL;
811
812 offset = pgoff << PAGE_SHIFT;
813 if (offset > mtd->size - len)
814 return (unsigned long) -EINVAL;
815
816 return mtd->get_unmapped_area(mtd, len, offset, flags);
817 }
818
819 /* can't map directly */
820 return (unsigned long) -ENOSYS;
821}
822#endif
823
824/*
825 * set up a mapping for shared memory segments
826 */
827static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
828{
829#ifdef CONFIG_MMU
830 struct mtd_file_info *mfi = file->private_data;
831 struct mtd_info *mtd = mfi->mtd;
832
833 if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
834 return 0;
835 return -ENOSYS;
836#else
837 return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
838#endif
839}
840
784static const struct file_operations mtd_fops = { 841static const struct file_operations mtd_fops = {
785 .owner = THIS_MODULE, 842 .owner = THIS_MODULE,
786 .llseek = mtd_lseek, 843 .llseek = mtd_lseek,
@@ -789,6 +846,10 @@ static const struct file_operations mtd_fops = {
789 .ioctl = mtd_ioctl, 846 .ioctl = mtd_ioctl,
790 .open = mtd_open, 847 .open = mtd_open,
791 .release = mtd_close, 848 .release = mtd_close,
849 .mmap = mtd_mmap,
850#ifndef CONFIG_MMU
851 .get_unmapped_area = mtd_get_unmapped_area,
852#endif
792}; 853};
793 854
794static int __init init_mtdchar(void) 855static int __init init_mtdchar(void)