diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 14:56:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 14:56:26 -0700 |
commit | 22ae77bc7ac115b9d518d5cbc13d39317079b2b0 (patch) | |
tree | 574b7af678c0b1ad2c891ac5066292746788ece8 /drivers/mtd/mtdchar.c | |
parent | e379ec7c42343c6b6ef06a98de7c94db41c1423e (diff) | |
parent | 30bbf1406714cf464c56e96e4ad6a291907f5023 (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (53 commits)
[MTD] struct device - replace bus_id with dev_name(), dev_set_name()
[MTD] [NOR] Fixup for Numonyx M29W128 chips
[MTD] mtdpart: Make ecc_stats more realistic.
powerpc/85xx: TQM8548: Update DTS file for multi-chip support
powerpc: NAND: FSL UPM: document new bindings
[MTD] [NAND] FSL-UPM: Add wait flags to support board/chip specific delays
[MTD] [NAND] FSL-UPM: add multi chip support
[MTD] [NOR] Add device parent info to physmap_of
[MTD] [NAND] Add support for NAND on the Socrates board
[MTD] [NAND] Add support for 4KiB pages.
[MTD] sysfs support should not depend on CONFIG_PROC_FS
[MTD] [NAND] Add parent info for CAFÉ controller
[MTD] support driver model updates
[MTD] driver model updates (part 2)
[MTD] driver model updates
[MTD] [NAND] move gen_nand's probe function to .devinit.text
[MTD] [MAPS] move sa1100 flash's probe function to .devinit.text
[MTD] fix use after free in register_mtd_blktrans
[MTD] [MAPS] Drop now unused sharpsl-flash map
[MTD] ofpart: Check name property to determine partition nodes.
...
Manually fix trivial conflict in drivers/mtd/maps/Makefile
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r-- | drivers/mtd/mtdchar.c | 111 |
1 files changed, 69 insertions, 42 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index e9ec59e9a56..763d3f0a1f4 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -13,39 +13,13 @@ #include <linux/slab.h> #include <linux/sched.h> #include <linux/smp_lock.h> +#include <linux/backing-dev.h> #include <linux/mtd/mtd.h> #include <linux/mtd/compatmac.h> #include <asm/uaccess.h> -static struct class *mtd_class; - -static void mtd_notify_add(struct mtd_info* mtd) -{ - if (!mtd) - return; - - device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), - NULL, "mtd%d", mtd->index); - - device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), - NULL, "mtd%dro", mtd->index); -} - -static void mtd_notify_remove(struct mtd_info* mtd) -{ - if (!mtd) - return; - - device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2)); - device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1)); -} - -static struct mtd_notifier notifier = { - .add = mtd_notify_add, - .remove = mtd_notify_remove, -}; /* * Data structure to hold the pointer to the mtd device as well @@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode, struct file *file) goto out; } - if (MTD_ABSENT == mtd->type) { + if (mtd->type == MTD_ABSENT) { put_mtd_device(mtd); ret = -ENODEV; goto out; } + if (mtd->backing_dev_info) + file->f_mapping->backing_dev_info = mtd->backing_dev_info; + /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { put_mtd_device(mtd); @@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file, return ret; } /* memory_ioctl */ +/* + * try to determine where a shared mapping can be made + * - only supported for NOMMU at the moment (MMU can't doesn't copy private + * mappings) + */ +#ifndef CONFIG_MMU +static unsigned long mtd_get_unmapped_area(struct file *file, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags) +{ + struct mtd_file_info *mfi = file->private_data; + struct mtd_info *mtd = mfi->mtd; + + if (mtd->get_unmapped_area) { + unsigned long offset; + + if (addr != 0) + return (unsigned long) -EINVAL; + + if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT)) + return (unsigned long) -EINVAL; + + offset = pgoff << PAGE_SHIFT; + if (offset > mtd->size - len) + return (unsigned long) -EINVAL; + + return mtd->get_unmapped_area(mtd, len, offset, flags); + } + + /* can't map directly */ + return (unsigned long) -ENOSYS; +} +#endif + +/* + * set up a mapping for shared memory segments + */ +static int mtd_mmap(struct file *file, struct vm_area_struct *vma) +{ +#ifdef CONFIG_MMU + struct mtd_file_info *mfi = file->private_data; + struct mtd_info *mtd = mfi->mtd; + + if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) + return 0; + return -ENOSYS; +#else + return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS; +#endif +} + static const struct file_operations mtd_fops = { .owner = THIS_MODULE, .llseek = mtd_lseek, @@ -789,39 +819,36 @@ static const struct file_operations mtd_fops = { .ioctl = mtd_ioctl, .open = mtd_open, .release = mtd_close, + .mmap = mtd_mmap, +#ifndef CONFIG_MMU + .get_unmapped_area = mtd_get_unmapped_area, +#endif }; static int __init init_mtdchar(void) { - if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) { + int status; + + status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops); + if (status < 0) { printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", MTD_CHAR_MAJOR); - return -EAGAIN; } - mtd_class = class_create(THIS_MODULE, "mtd"); - - if (IS_ERR(mtd_class)) { - printk(KERN_ERR "Error creating mtd class.\n"); - unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); - return PTR_ERR(mtd_class); - } - - register_mtd_user(¬ifier); - return 0; + return status; } static void __exit cleanup_mtdchar(void) { - unregister_mtd_user(¬ifier); - class_destroy(mtd_class); unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); } module_init(init_mtdchar); module_exit(cleanup_mtdchar); +MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); MODULE_DESCRIPTION("Direct character-device access to MTD devices"); +MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR); |