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