11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip) 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 42f82af08fcc7dc01a7e98a49a5995a77e32a2925Nicolas Pitre * (C) 2000 Nicolas Pitre <nico@fluxnic.net> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This code is GPL 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 134e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/mtd.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/map.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/partitions.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/hardware/dec21285.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach-types.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mtd_info *dc21285_mtd; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_ARCH_NETWINDER 2769f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner/* 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is really ugly, but it seams to be the only 2969f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner * realiable way to do it, as the cpld state machine 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is unpredictible. So we have a 25us penalty per 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write access. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void nw_en_write(void) 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we want to write a bit pattern XXX1 to Xilinx to enable 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the write gate, which will be open for about the next 2ms. 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4170d13e083c8589dd3edc2313777655da39cb3568Russell King spin_lock_irqsave(&nw_gpio_lock, flags); 4270d13e083c8589dd3edc2313777655da39cb3568Russell King nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE); 4370d13e083c8589dd3edc2313777655da39cb3568Russell King spin_unlock_irqrestore(&nw_gpio_lock, flags); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * let the ISA bus to catch on... 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(25); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define nw_en_write() do { } while (0) 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic map_word dc21285_read8(struct map_info *map, unsigned long ofs) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word val; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val.x[0] = *(uint8_t*)(map->virt + ofs); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return val; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic map_word dc21285_read16(struct map_info *map, unsigned long ofs) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word val; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val.x[0] = *(uint16_t*)(map->virt + ofs); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return val; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic map_word dc21285_read32(struct map_info *map, unsigned long ofs) 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word val; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val.x[0] = *(uint32_t*)(map->virt + ofs); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return val; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(to, (void*)(map->virt + from), len); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr) 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (machine_is_netwinder()) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nw_en_write(); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *CSR_ROMWRITEREG = adr & 3; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr &= ~3; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(uint8_t*)(map->virt + adr) = d.x[0]; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr) 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (machine_is_netwinder()) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nw_en_write(); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *CSR_ROMWRITEREG = adr & 3; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr &= ~3; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(uint16_t*)(map->virt + adr) = d.x[0]; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (machine_is_netwinder()) 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nw_en_write(); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(uint32_t*)(map->virt + adr) = d.x[0]; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (len > 0) { 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word d; 10975b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr d.x[0] = *((uint32_t*)from); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_write32(map, d, to); 11175b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr from += 4; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds to += 4; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= 4; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len) 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (len > 0) { 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word d; 12175b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr d.x[0] = *((uint16_t*)from); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_write16(map, d, to); 12375b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr from += 2; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds to += 2; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= 2; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_word d; 13275b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr d.x[0] = *((uint8_t*)from); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_write8(map, d, to); 13475b84e94aa9fa74bda9a393b55ef6778b90eb1a8Martin Michlmayr from++; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds to++; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len--; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct map_info dc21285_map = { 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "DC21285 flash", 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .phys = NO_XIP, 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .size = 16*1024*1024, 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .copy_from = dc21285_copy_from, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Partition stuff */ 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 14969f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_dc21285(void) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Determine bankwidth */ 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (*CSR_SA110_CNTL & (3<<14)) { 15469f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner case SA110_CNTL_ROMWIDTH_8: 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.bankwidth = 1; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.read = dc21285_read8; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.write = dc21285_write8; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.copy_to = dc21285_copy_to_8; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16069f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner case SA110_CNTL_ROMWIDTH_16: 16169f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner dc21285_map.bankwidth = 2; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.read = dc21285_read16; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.write = dc21285_write16; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.copy_to = dc21285_copy_to_16; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16669f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner case SA110_CNTL_ROMWIDTH_32: 16769f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner dc21285_map.bankwidth = 4; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.read = dc21285_read32; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.write = dc21285_write32; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.copy_to = dc21285_copy_to_32; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk (KERN_ERR "DC21285 flash: undefined bankwidth\n"); 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENXIO; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n", 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.bankwidth*8); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Let's map the flash area */ 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dc21285_map.virt) { 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Failed to ioremap\n"); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (machine_is_ebsa285()) { 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dc21285_mtd) { 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(dc21285_map.virt); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENXIO; 19569f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner } 19669f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dc21285_mtd->owner = THIS_MODULE; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19942d7fbe223ab878b23de9e3b0166f8cd665a2aa5Artem Bityutskiy mtd_device_parse_register(dc21285_mtd, probes, NULL, NULL, 0); 20069f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(machine_is_ebsa285()) { 20269f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner /* 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Flash timing is determined with bits 19-16 of the 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CSR_SA110_CNTL. The value is the number of wait cycles, or 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 for 16 cycles (the default). Cycles are 20 ns. 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Here we use 7 for 140 ns flash chips. 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* access time */ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* burst time */ 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* tristate time */ 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21569f34c98c1416eb74c55e38a21dbf3e294966514Thomas Gleixner 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit cleanup_dc21285(void) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 221bc2ffddc46be60c12462f8ae60ed0eae2a62a17bJamie Iles mtd_device_unregister(dc21285_mtd); 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_destroy(dc21285_mtd); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(dc21285_map.virt); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(init_dc21285); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(cleanup_dc21285); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2312f82af08fcc7dc01a7e98a49a5995a77e32a2925Nicolas PitreMODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>"); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("MTD map driver for DC21285 boards"); 233