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