1/* 2 * Flash device on lasat 100 and 200 boards 3 * 4 */ 5 6#include <linux/module.h> 7#include <linux/types.h> 8#include <linux/kernel.h> 9#include <asm/io.h> 10#include <linux/mtd/mtd.h> 11#include <linux/mtd/map.h> 12#include <linux/mtd/partitions.h> 13#include <linux/config.h> 14#include <asm/lasat/lasat.h> 15#include <asm/lasat/lasat_mtd.h> 16 17static struct mtd_info *mymtd; 18 19static __u8 sp_read8(struct map_info *map, unsigned long ofs) 20{ 21 return __raw_readb(map->map_priv_1 + ofs); 22} 23 24static __u16 sp_read16(struct map_info *map, unsigned long ofs) 25{ 26 return __raw_readw(map->map_priv_1 + ofs); 27} 28 29static __u32 sp_read32(struct map_info *map, unsigned long ofs) 30{ 31 return __raw_readl(map->map_priv_1 + ofs); 32} 33 34static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 35{ 36 memcpy_fromio(to, map->map_priv_1 + from, len); 37} 38 39static void sp_write8(struct map_info *map, __u8 d, unsigned long adr) 40{ 41 __raw_writeb(d, map->map_priv_1 + adr); 42 mb(); 43} 44 45static void sp_write16(struct map_info *map, __u16 d, unsigned long adr) 46{ 47 __raw_writew(d, map->map_priv_1 + adr); 48 mb(); 49} 50 51static void sp_write32(struct map_info *map, __u32 d, unsigned long adr) 52{ 53 __raw_writel(d, map->map_priv_1 + adr); 54 mb(); 55} 56 57static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 58{ 59 memcpy_toio(map->map_priv_1 + to, from, len); 60} 61 62static struct map_info sp_map = { 63 name: "SP flash", 64 buswidth: 4, 65 read8: sp_read8, 66 read16: sp_read16, 67 read32: sp_read32, 68 copy_from: sp_copy_from, 69 write8: sp_write8, 70 write16: sp_write16, 71 write32: sp_write32, 72 copy_to: sp_copy_to 73}; 74 75static struct mtd_partition partition_info[LASAT_MTD_LAST]; 76static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; 77 78static int __init init_sp(void) 79{ 80 int i; 81 /* this does not play well with the old flash code which 82 * protects and uprotects the flash when necessary */ 83 printk(KERN_NOTICE "Unprotecting flash\n"); 84 *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; 85 86 sp_map.map_priv_1 = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); 87 sp_map.size = lasat_board_info.li_flash_size; 88 89 printk(KERN_NOTICE "sp flash device: %lx at %lx\n", 90 sp_map.size, sp_map.map_priv_1); 91 92 for (i=0; i < LASAT_MTD_LAST; i++) 93 partition_info[i].name = lasat_mtd_partnames[i]; 94 95 mymtd = do_map_probe("cfi_probe", &sp_map); 96 if (mymtd) { 97 u32 size, offset = 0; 98 99 mymtd->module = THIS_MODULE; 100 101 for (i=0; i < LASAT_MTD_LAST; i++) { 102 size = lasat_flash_partition_size(i); 103 partition_info[i].size = size; 104 partition_info[i].offset = offset; 105 offset += size; 106 } 107 108 add_mtd_partitions( mymtd, partition_info, LASAT_MTD_LAST ); 109 return 0; 110 } 111 112 return -ENXIO; 113} 114 115static void __exit cleanup_sp(void) 116{ 117 if (mymtd) { 118 del_mtd_partitions(mymtd); 119 map_destroy(mymtd); 120 } 121 if (sp_map.map_priv_1) { 122 sp_map.map_priv_1 = 0; 123 } 124} 125 126module_init(init_sp); 127module_exit(cleanup_sp); 128 129MODULE_LICENSE("GPL"); 130MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>"); 131MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver"); 132