1/* 2 * Flash on Cirrus CDB89712 3 * 4 * $Id: cdb89712.c,v 1.1.1.1 2008/10/15 03:26:35 james26_jang Exp $ 5 */ 6 7#include <linux/module.h> 8#include <linux/types.h> 9#include <linux/kernel.h> 10#include <linux/ioport.h> 11#include <asm/io.h> 12#include <asm/arch/hardware.h> 13#include <linux/mtd/mtd.h> 14#include <linux/mtd/map.h> 15#include <linux/mtd/partitions.h> 16 17 18 19__u8 cdb89712_read8(struct map_info *map, unsigned long ofs) 20{ 21 return __raw_readb(map->map_priv_1 + ofs); 22} 23 24__u16 cdb89712_read16(struct map_info *map, unsigned long ofs) 25{ 26 return __raw_readw(map->map_priv_1 + ofs); 27} 28 29__u32 cdb89712_read32(struct map_info *map, unsigned long ofs) 30{ 31 return __raw_readl(map->map_priv_1 + ofs); 32} 33 34void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr) 35{ 36 __raw_writeb(d, map->map_priv_1 + adr); 37 mb(); 38} 39 40void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr) 41{ 42 __raw_writew(d, map->map_priv_1 + adr); 43 mb(); 44} 45 46void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr) 47{ 48 __raw_writel(d, map->map_priv_1 + adr); 49 mb(); 50} 51 52void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 53{ 54 // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to); 55 memcpy_fromio(to, map->map_priv_1 + from, len); 56} 57 58void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 59{ 60 while(len) { 61 __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); 62 from++; 63 to++; 64 len--; 65 } 66} 67 68 69static struct mtd_info *flash_mtd; 70 71struct map_info cdb89712_flash_map = { 72 name: "flash", 73 size: FLASH_SIZE, 74 buswidth: FLASH_WIDTH, 75 read8: cdb89712_read8, 76 read16: cdb89712_read16, 77 read32: cdb89712_read32, 78 copy_from: cdb89712_copy_from, 79 write8: cdb89712_write8, 80 write16: cdb89712_write16, 81 write32: cdb89712_write32, 82 copy_to: cdb89712_copy_to 83}; 84 85struct resource cdb89712_flash_resource = { 86 name: "Flash", 87 start: FLASH_START, 88 end: FLASH_START + FLASH_SIZE - 1, 89 flags: IORESOURCE_IO | IORESOURCE_BUSY, 90}; 91 92static int __init init_cdb89712_flash (void) 93{ 94 int err; 95 96 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) { 97 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n"); 98 err = -EBUSY; 99 goto out; 100 } 101 102 cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); 103 if (!cdb89712_flash_map.map_priv_1) { 104 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); 105 err = -EIO; 106 goto out_resource; 107 } 108 109 flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map); 110 if (!flash_mtd) { 111 flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map); 112 if (flash_mtd) 113 flash_mtd->erasesize = 0x10000; 114 } 115 if (!flash_mtd) { 116 printk("FLASH probe failed\n"); 117 err = -ENXIO; 118 goto out_ioremap; 119 } 120 121 flash_mtd->module = THIS_MODULE; 122 123 if (add_mtd_device(flash_mtd)) { 124 printk("FLASH device addition failed\n"); 125 err = -ENOMEM; 126 goto out_probe; 127 } 128 129 return 0; 130 131out_probe: 132 map_destroy(flash_mtd); 133 flash_mtd = 0; 134out_ioremap: 135 iounmap((void *)cdb89712_flash_map.map_priv_1); 136out_resource: 137 release_resource (&cdb89712_flash_resource); 138out: 139 return err; 140} 141 142 143 144 145 146static struct mtd_info *sram_mtd; 147 148struct map_info cdb89712_sram_map = { 149 name: "SRAM", 150 size: SRAM_SIZE, 151 buswidth: SRAM_WIDTH, 152 read8: cdb89712_read8, 153 read16: cdb89712_read16, 154 read32: cdb89712_read32, 155 copy_from: cdb89712_copy_from, 156 write8: cdb89712_write8, 157 write16: cdb89712_write16, 158 write32: cdb89712_write32, 159 copy_to: cdb89712_copy_to 160}; 161 162struct resource cdb89712_sram_resource = { 163 name: "SRAM", 164 start: SRAM_START, 165 end: SRAM_START + SRAM_SIZE - 1, 166 flags: IORESOURCE_IO | IORESOURCE_BUSY, 167}; 168 169static int __init init_cdb89712_sram (void) 170{ 171 int err; 172 173 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) { 174 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n"); 175 err = -EBUSY; 176 goto out; 177 } 178 179 cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE); 180 if (!cdb89712_sram_map.map_priv_1) { 181 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); 182 err = -EIO; 183 goto out_resource; 184 } 185 186 sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map); 187 if (!sram_mtd) { 188 printk("SRAM probe failed\n"); 189 err = -ENXIO; 190 goto out_ioremap; 191 } 192 193 sram_mtd->module = THIS_MODULE; 194 sram_mtd->erasesize = 16; 195 196 if (add_mtd_device(sram_mtd)) { 197 printk("SRAM device addition failed\n"); 198 err = -ENOMEM; 199 goto out_probe; 200 } 201 202 return 0; 203 204out_probe: 205 map_destroy(sram_mtd); 206 sram_mtd = 0; 207out_ioremap: 208 iounmap((void *)cdb89712_sram_map.map_priv_1); 209out_resource: 210 release_resource (&cdb89712_sram_resource); 211out: 212 return err; 213} 214 215 216 217 218 219 220 221static struct mtd_info *bootrom_mtd; 222 223struct map_info cdb89712_bootrom_map = { 224 name: "BootROM", 225 size: BOOTROM_SIZE, 226 buswidth: BOOTROM_WIDTH, 227 read8: cdb89712_read8, 228 read16: cdb89712_read16, 229 read32: cdb89712_read32, 230 copy_from: cdb89712_copy_from, 231}; 232 233struct resource cdb89712_bootrom_resource = { 234 name: "BootROM", 235 start: BOOTROM_START, 236 end: BOOTROM_START + BOOTROM_SIZE - 1, 237 flags: IORESOURCE_IO | IORESOURCE_BUSY, 238}; 239 240static int __init init_cdb89712_bootrom (void) 241{ 242 int err; 243 244 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) { 245 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n"); 246 err = -EBUSY; 247 goto out; 248 } 249 250 cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE); 251 if (!cdb89712_bootrom_map.map_priv_1) { 252 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); 253 err = -EIO; 254 goto out_resource; 255 } 256 257 bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map); 258 if (!bootrom_mtd) { 259 printk("BootROM probe failed\n"); 260 err = -ENXIO; 261 goto out_ioremap; 262 } 263 264 bootrom_mtd->module = THIS_MODULE; 265 bootrom_mtd->erasesize = 0x10000; 266 267 if (add_mtd_device(bootrom_mtd)) { 268 printk("BootROM device addition failed\n"); 269 err = -ENOMEM; 270 goto out_probe; 271 } 272 273 return 0; 274 275out_probe: 276 map_destroy(bootrom_mtd); 277 bootrom_mtd = 0; 278out_ioremap: 279 iounmap((void *)cdb89712_bootrom_map.map_priv_1); 280out_resource: 281 release_resource (&cdb89712_bootrom_resource); 282out: 283 return err; 284} 285 286 287 288 289 290static int __init init_cdb89712_maps(void) 291{ 292 293 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n", 294 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START); 295 296 init_cdb89712_flash(); 297 init_cdb89712_sram(); 298 init_cdb89712_bootrom(); 299 300 return 0; 301} 302 303 304static void __exit cleanup_cdb89712_maps(void) 305{ 306 if (sram_mtd) { 307 del_mtd_device(sram_mtd); 308 map_destroy(sram_mtd); 309 iounmap((void *)cdb89712_sram_map.map_priv_1); 310 release_resource (&cdb89712_sram_resource); 311 } 312 313 if (flash_mtd) { 314 del_mtd_device(flash_mtd); 315 map_destroy(flash_mtd); 316 iounmap((void *)cdb89712_flash_map.map_priv_1); 317 release_resource (&cdb89712_flash_resource); 318 } 319 320 if (bootrom_mtd) { 321 del_mtd_device(bootrom_mtd); 322 map_destroy(bootrom_mtd); 323 iounmap((void *)cdb89712_bootrom_map.map_priv_1); 324 release_resource (&cdb89712_bootrom_resource); 325 } 326} 327 328module_init(init_cdb89712_maps); 329module_exit(cleanup_cdb89712_maps); 330 331MODULE_AUTHOR("Ray L"); 332MODULE_DESCRIPTION("ARM CDB89712 map driver"); 333MODULE_LICENSE("GPL"); 334