1 /* 2 * Flash and EPROM on Hitachi Solution Engine and similar boards. 3 * 4 * (C) 2001 Red Hat, Inc. 5 * 6 * GPL'd 7 */ 8 9 #include <linux/module.h> 10 #include <linux/types.h> 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <asm/io.h> 14 #include <linux/mtd/mtd.h> 15 #include <linux/mtd/map.h> 16 #include <linux/mtd/partitions.h> 17 #include <linux/errno.h> 18 19 static struct mtd_info *flash_mtd; 20 static struct mtd_info *eprom_mtd; 21 22 static struct mtd_partition *parsed_parts; 23 24 struct map_info soleng_eprom_map = { 25 .name = "Solution Engine EPROM", 26 .size = 0x400000, 27 .bankwidth = 4, 28 }; 29 30 struct map_info soleng_flash_map = { 31 .name = "Solution Engine FLASH", 32 .size = 0x400000, 33 .bankwidth = 4, 34 }; 35 36 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 37 38 #ifdef CONFIG_MTD_SUPERH_RESERVE 39 static struct mtd_partition superh_se_partitions[] = { 40 /* Reserved for boot code, read-only */ 41 { 42 .name = "flash_boot", 43 .offset = 0x00000000, 44 .size = CONFIG_MTD_SUPERH_RESERVE, 45 .mask_flags = MTD_WRITEABLE, 46 }, 47 /* All else is writable (e.g. JFFS) */ 48 { 49 .name = "Flash FS", 50 .offset = MTDPART_OFS_NXTBLK, 51 .size = MTDPART_SIZ_FULL, 52 } 53 }; 54 #endif /* CONFIG_MTD_SUPERH_RESERVE */ 55 56 static int __init init_soleng_maps(void) 57 { 58 int nr_parts = 0; 59 60 /* First probe at offset 0 */ 61 soleng_flash_map.phys = 0; 62 soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0); 63 soleng_eprom_map.phys = 0x01000000; 64 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); 65 simple_map_init(&soleng_eprom_map); 66 simple_map_init(&soleng_flash_map); 67 68 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); 69 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); 70 if (!flash_mtd) { 71 /* Not there. Try swapping */ 72 printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n"); 73 soleng_flash_map.phys = 0x01000000; 74 soleng_flash_map.virt = P2SEGADDR(0x01000000); 75 soleng_eprom_map.phys = 0; 76 soleng_eprom_map.virt = P1SEGADDR(0); 77 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); 78 if (!flash_mtd) { 79 /* Eep. */ 80 printk(KERN_NOTICE "Flash chips not detected at either possible location.\n"); 81 return -ENXIO; 82 } 83 } 84 printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n", 85 soleng_flash_map.phys & 0x1fffffff, 86 soleng_eprom_map.phys & 0x1fffffff); 87 flash_mtd->owner = THIS_MODULE; 88 89 eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); 90 if (eprom_mtd) { 91 eprom_mtd->owner = THIS_MODULE; 92 mtd_device_register(eprom_mtd, NULL, 0); 93 } 94 95 nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); 96 97 #ifdef CONFIG_MTD_SUPERH_RESERVE 98 if (nr_parts <= 0) { 99 printk(KERN_NOTICE "Using configured partition at 0x%08x.\n", 100 CONFIG_MTD_SUPERH_RESERVE); 101 parsed_parts = superh_se_partitions; 102 nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts); 103 } 104 #endif /* CONFIG_MTD_SUPERH_RESERVE */ 105 106 if (nr_parts > 0) 107 mtd_device_register(flash_mtd, parsed_parts, nr_parts); 108 else 109 mtd_device_register(flash_mtd, NULL, 0); 110 111 return 0; 112 } 113 114 static void __exit cleanup_soleng_maps(void) 115 { 116 if (eprom_mtd) { 117 mtd_device_unregister(eprom_mtd); 118 map_destroy(eprom_mtd); 119 } 120 121 if (parsed_parts) 122 mtd_device_unregister(flash_mtd); 123 else 124 mtd_device_unregister(flash_mtd); 125 map_destroy(flash_mtd); 126 } 127 128 module_init(init_soleng_maps); 129 module_exit(cleanup_soleng_maps); 130 131 MODULE_LICENSE("GPL"); 132 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 133 MODULE_DESCRIPTION("MTD map driver for Hitachi SolutionEngine (and similar) boards"); 134 135