11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Common code to handle map devices which are simple ROM 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) 2000 Red Hat. GPL'd. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/mtd.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/map.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void maprom_nop (struct mtd_info *); 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mtd_info *map_rom_probe(struct map_info *map); 215f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Coxstatic int maprom_erase (struct mtd_info *mtd, struct erase_info *info); 22402d326519c1a4859c527702383f4e60f606ef52David Howellsstatic unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long, 23402d326519c1a4859c527702383f4e60f606ef52David Howells unsigned long, unsigned long); 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mtd_chip_driver maprom_chipdrv = { 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = map_rom_probe, 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "map_rom", 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .module = THIS_MODULE 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mtd_info *map_rom_probe(struct map_info *map) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mtd_info *mtd; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3595b93a0cd46682c6d9e8eea803fda510cb6b863aBurman Yan mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mtd) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map->fldrv = &maprom_chipdrv; 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->priv = map; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->name = map->name; 4221c8db9eff95260e543535dfc6f27164c4c0c0ffDavid Woodhouse mtd->type = MTD_ROM; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->size = map->size; 443c3c10bba1e4ccb75b41442e45c1a072f6cded19Artem Bityutskiy mtd->_get_unmapped_area = maprom_unmapped_area; 453c3c10bba1e4ccb75b41442e45c1a072f6cded19Artem Bityutskiy mtd->_read = maprom_read; 463c3c10bba1e4ccb75b41442e45c1a072f6cded19Artem Bityutskiy mtd->_write = maprom_write; 473c3c10bba1e4ccb75b41442e45c1a072f6cded19Artem Bityutskiy mtd->_sync = maprom_nop; 483c3c10bba1e4ccb75b41442e45c1a072f6cded19Artem Bityutskiy mtd->_erase = maprom_erase; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->flags = MTD_CAP_ROM; 50e369d62e92d526a7ed641e2f0b2978fb0ce366c5Joern Engel mtd->erasesize = map->size; 5117ffc7ba6d7ea68b8d5f55a5ca1b87163e69720dArtem B. Bityutskiy mtd->writesize = 1; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __module_get(THIS_MODULE); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mtd; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 58402d326519c1a4859c527702383f4e60f606ef52David Howells/* 59402d326519c1a4859c527702383f4e60f606ef52David Howells * Allow NOMMU mmap() to directly map the device (if not NULL) 60402d326519c1a4859c527702383f4e60f606ef52David Howells * - return the address to which the offset maps 61402d326519c1a4859c527702383f4e60f606ef52David Howells * - return -ENOSYS to indicate refusal to do the mapping 62402d326519c1a4859c527702383f4e60f606ef52David Howells */ 63402d326519c1a4859c527702383f4e60f606ef52David Howellsstatic unsigned long maprom_unmapped_area(struct mtd_info *mtd, 64402d326519c1a4859c527702383f4e60f606ef52David Howells unsigned long len, 65402d326519c1a4859c527702383f4e60f606ef52David Howells unsigned long offset, 66402d326519c1a4859c527702383f4e60f606ef52David Howells unsigned long flags) 67402d326519c1a4859c527702383f4e60f606ef52David Howells{ 68402d326519c1a4859c527702383f4e60f606ef52David Howells struct map_info *map = mtd->priv; 69402d326519c1a4859c527702383f4e60f606ef52David Howells return (unsigned long) map->virt + offset; 70402d326519c1a4859c527702383f4e60f606ef52David Howells} 71402d326519c1a4859c527702383f4e60f606ef52David Howells 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct map_info *map = mtd->priv; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_copy_from(map, buf, from, len); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *retlen = len; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void maprom_nop(struct mtd_info *mtd) 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Nothing to see here */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 88664addc248d2fed68d013d26ff2fc796d7134259Artem Bityutskiy return -EROFS; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 915f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Coxstatic int maprom_erase (struct mtd_info *mtd, struct erase_info *info) 925f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Cox{ 935f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Cox /* We do our best 8) */ 945f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Cox return -EROFS; 955f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Cox} 965f877607cdfe8b60bf96fb96e527e0ce2a21e68bAlan Cox 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init map_rom_init(void) 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register_mtd_chip_driver(&maprom_chipdrv); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit map_rom_exit(void) 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_mtd_chip_driver(&maprom_chipdrv); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(map_rom_init); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(map_rom_exit); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("MTD chip driver for ROM chips"); 114