18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Common code to handle map devices which are simple ROM 38c2ecf20Sopenharmony_ci * (C) 2000 Red Hat. GPL'd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/types.h> 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include <asm/io.h> 108c2ecf20Sopenharmony_ci#include <asm/byteorder.h> 118c2ecf20Sopenharmony_ci#include <linux/errno.h> 128c2ecf20Sopenharmony_ci#include <linux/slab.h> 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/of.h> 158c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 168c2ecf20Sopenharmony_ci#include <linux/mtd/map.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 198c2ecf20Sopenharmony_cistatic int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 208c2ecf20Sopenharmony_cistatic void maprom_nop (struct mtd_info *); 218c2ecf20Sopenharmony_cistatic struct mtd_info *map_rom_probe(struct map_info *map); 228c2ecf20Sopenharmony_cistatic int maprom_erase (struct mtd_info *mtd, struct erase_info *info); 238c2ecf20Sopenharmony_cistatic int maprom_point (struct mtd_info *mtd, loff_t from, size_t len, 248c2ecf20Sopenharmony_ci size_t *retlen, void **virt, resource_size_t *phys); 258c2ecf20Sopenharmony_cistatic int maprom_unpoint(struct mtd_info *mtd, loff_t from, size_t len); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic struct mtd_chip_driver maprom_chipdrv = { 298c2ecf20Sopenharmony_ci .probe = map_rom_probe, 308c2ecf20Sopenharmony_ci .name = "map_rom", 318c2ecf20Sopenharmony_ci .module = THIS_MODULE 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic unsigned int default_erasesize(struct map_info *map) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci const __be32 *erase_size = NULL; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci erase_size = of_get_property(map->device_node, "erase-size", NULL); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return !erase_size ? map->size : be32_to_cpu(*erase_size); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic struct mtd_info *map_rom_probe(struct map_info *map) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci struct mtd_info *mtd; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); 488c2ecf20Sopenharmony_ci if (!mtd) 498c2ecf20Sopenharmony_ci return NULL; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci map->fldrv = &maprom_chipdrv; 528c2ecf20Sopenharmony_ci mtd->priv = map; 538c2ecf20Sopenharmony_ci mtd->name = map->name; 548c2ecf20Sopenharmony_ci mtd->type = MTD_ROM; 558c2ecf20Sopenharmony_ci mtd->size = map->size; 568c2ecf20Sopenharmony_ci mtd->_point = maprom_point; 578c2ecf20Sopenharmony_ci mtd->_unpoint = maprom_unpoint; 588c2ecf20Sopenharmony_ci mtd->_read = maprom_read; 598c2ecf20Sopenharmony_ci mtd->_write = maprom_write; 608c2ecf20Sopenharmony_ci mtd->_sync = maprom_nop; 618c2ecf20Sopenharmony_ci mtd->_erase = maprom_erase; 628c2ecf20Sopenharmony_ci mtd->flags = MTD_CAP_ROM; 638c2ecf20Sopenharmony_ci mtd->erasesize = default_erasesize(map); 648c2ecf20Sopenharmony_ci mtd->writesize = 1; 658c2ecf20Sopenharmony_ci mtd->writebufsize = 1; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci __module_get(THIS_MODULE); 688c2ecf20Sopenharmony_ci return mtd; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int maprom_point(struct mtd_info *mtd, loff_t from, size_t len, 738c2ecf20Sopenharmony_ci size_t *retlen, void **virt, resource_size_t *phys) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci struct map_info *map = mtd->priv; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (!map->virt) 788c2ecf20Sopenharmony_ci return -EINVAL; 798c2ecf20Sopenharmony_ci *virt = map->virt + from; 808c2ecf20Sopenharmony_ci if (phys) 818c2ecf20Sopenharmony_ci *phys = map->phys + from; 828c2ecf20Sopenharmony_ci *retlen = len; 838c2ecf20Sopenharmony_ci return 0; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic int maprom_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci return 0; 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci struct map_info *map = mtd->priv; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci map_copy_from(map, buf, from, len); 968c2ecf20Sopenharmony_ci *retlen = len; 978c2ecf20Sopenharmony_ci return 0; 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic void maprom_nop(struct mtd_info *mtd) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci /* Nothing to see here */ 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci return -EROFS; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic int maprom_erase (struct mtd_info *mtd, struct erase_info *info) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci /* We do our best 8) */ 1138c2ecf20Sopenharmony_ci return -EROFS; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int __init map_rom_init(void) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci register_mtd_chip_driver(&maprom_chipdrv); 1198c2ecf20Sopenharmony_ci return 0; 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic void __exit map_rom_exit(void) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci unregister_mtd_chip_driver(&maprom_chipdrv); 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cimodule_init(map_rom_init); 1288c2ecf20Sopenharmony_cimodule_exit(map_rom_exit); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1318c2ecf20Sopenharmony_ciMODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 1328c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MTD chip driver for ROM chips"); 133