0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/types.h>
0008 #include <linux/kernel.h>
0009 #include <asm/io.h>
0010 #include <asm/byteorder.h>
0011 #include <linux/errno.h>
0012 #include <linux/slab.h>
0013 #include <linux/init.h>
0014 #include <linux/of.h>
0015 #include <linux/mtd/mtd.h>
0016 #include <linux/mtd/map.h>
0017
0018 static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
0019 static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
0020 static void maprom_nop (struct mtd_info *);
0021 static struct mtd_info *map_rom_probe(struct map_info *map);
0022 static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
0023 static int maprom_point (struct mtd_info *mtd, loff_t from, size_t len,
0024 size_t *retlen, void **virt, resource_size_t *phys);
0025 static int maprom_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
0026
0027
0028 static struct mtd_chip_driver maprom_chipdrv = {
0029 .probe = map_rom_probe,
0030 .name = "map_rom",
0031 .module = THIS_MODULE
0032 };
0033
0034 static unsigned int default_erasesize(struct map_info *map)
0035 {
0036 const __be32 *erase_size = NULL;
0037
0038 erase_size = of_get_property(map->device_node, "erase-size", NULL);
0039
0040 return !erase_size ? map->size : be32_to_cpu(*erase_size);
0041 }
0042
0043 static struct mtd_info *map_rom_probe(struct map_info *map)
0044 {
0045 struct mtd_info *mtd;
0046
0047 mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
0048 if (!mtd)
0049 return NULL;
0050
0051 map->fldrv = &maprom_chipdrv;
0052 mtd->priv = map;
0053 mtd->name = map->name;
0054 mtd->type = MTD_ROM;
0055 mtd->size = map->size;
0056 mtd->_point = maprom_point;
0057 mtd->_unpoint = maprom_unpoint;
0058 mtd->_read = maprom_read;
0059 mtd->_write = maprom_write;
0060 mtd->_sync = maprom_nop;
0061 mtd->_erase = maprom_erase;
0062 mtd->flags = MTD_CAP_ROM;
0063 mtd->erasesize = default_erasesize(map);
0064 mtd->writesize = 1;
0065 mtd->writebufsize = 1;
0066
0067 __module_get(THIS_MODULE);
0068 return mtd;
0069 }
0070
0071
0072 static int maprom_point(struct mtd_info *mtd, loff_t from, size_t len,
0073 size_t *retlen, void **virt, resource_size_t *phys)
0074 {
0075 struct map_info *map = mtd->priv;
0076
0077 if (!map->virt)
0078 return -EINVAL;
0079 *virt = map->virt + from;
0080 if (phys)
0081 *phys = map->phys + from;
0082 *retlen = len;
0083 return 0;
0084 }
0085
0086 static int maprom_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
0087 {
0088 return 0;
0089 }
0090
0091 static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
0092 {
0093 struct map_info *map = mtd->priv;
0094
0095 map_copy_from(map, buf, from, len);
0096 *retlen = len;
0097 return 0;
0098 }
0099
0100 static void maprom_nop(struct mtd_info *mtd)
0101 {
0102
0103 }
0104
0105 static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
0106 {
0107 return -EROFS;
0108 }
0109
0110 static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
0111 {
0112
0113 return -EROFS;
0114 }
0115
0116 static int __init map_rom_init(void)
0117 {
0118 register_mtd_chip_driver(&maprom_chipdrv);
0119 return 0;
0120 }
0121
0122 static void __exit map_rom_exit(void)
0123 {
0124 unregister_mtd_chip_driver(&maprom_chipdrv);
0125 }
0126
0127 module_init(map_rom_init);
0128 module_exit(map_rom_exit);
0129
0130 MODULE_LICENSE("GPL");
0131 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
0132 MODULE_DESCRIPTION("MTD chip driver for ROM chips");