1/* 2 * $Id: mainstone-flash.c,v 1.1.1.1 2007/08/03 18:52:43 Exp $ 3 * 4 * Map driver for the Mainstone developer platform. 5 * 6 * Author: Nicolas Pitre 7 * Copyright: (C) 2001 MontaVista Software Inc. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14#include <linux/module.h> 15#include <linux/types.h> 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/dma-mapping.h> 19#include <linux/slab.h> 20 21#include <linux/mtd/mtd.h> 22#include <linux/mtd/map.h> 23#include <linux/mtd/partitions.h> 24 25#include <asm/io.h> 26#include <asm/hardware.h> 27#include <asm/arch/pxa-regs.h> 28#include <asm/arch/mainstone.h> 29 30 31#define ROM_ADDR 0x00000000 32#define FLASH_ADDR 0x04000000 33 34#define WINDOW_SIZE 0x04000000 35 36static void mainstone_map_inval_cache(struct map_info *map, unsigned long from, 37 ssize_t len) 38{ 39 consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE); 40} 41 42static struct map_info mainstone_maps[2] = { { 43 .size = WINDOW_SIZE, 44 .phys = PXA_CS0_PHYS, 45 .inval_cache = mainstone_map_inval_cache, 46}, { 47 .size = WINDOW_SIZE, 48 .phys = PXA_CS1_PHYS, 49 .inval_cache = mainstone_map_inval_cache, 50} }; 51 52static struct mtd_partition mainstone_partitions[] = { 53 { 54 .name = "Bootloader", 55 .size = 0x00040000, 56 .offset = 0, 57 .mask_flags = MTD_WRITEABLE /* force read-only */ 58 },{ 59 .name = "Kernel", 60 .size = 0x00400000, 61 .offset = 0x00040000, 62 },{ 63 .name = "Filesystem", 64 .size = MTDPART_SIZ_FULL, 65 .offset = 0x00440000 66 } 67}; 68 69static struct mtd_info *mymtds[2]; 70static struct mtd_partition *parsed_parts[2]; 71static int nr_parsed_parts[2]; 72 73static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 74 75static int __init init_mainstone(void) 76{ 77 int SW7 = 0; 78 int ret = 0, i; 79 80 mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4; 81 mainstone_maps[1].bankwidth = 4; 82 83 /* Compensate for SW7 which swaps the flash banks */ 84 mainstone_maps[SW7].name = "processor flash"; 85 mainstone_maps[SW7 ^ 1].name = "main board flash"; 86 87 printk(KERN_NOTICE "Mainstone configured to boot from %s\n", 88 mainstone_maps[0].name); 89 90 for (i = 0; i < 2; i++) { 91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys, 92 WINDOW_SIZE); 93 if (!mainstone_maps[i].virt) { 94 printk(KERN_WARNING "Failed to ioremap %s\n", 95 mainstone_maps[i].name); 96 if (!ret) 97 ret = -ENOMEM; 98 continue; 99 } 100 mainstone_maps[i].cached = 101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE); 102 if (!mainstone_maps[i].cached) 103 printk(KERN_WARNING "Failed to ioremap cached %s\n", 104 mainstone_maps[i].name); 105 simple_map_init(&mainstone_maps[i]); 106 107 printk(KERN_NOTICE 108 "Probing %s at physical address 0x%08lx" 109 " (%d-bit bankwidth)\n", 110 mainstone_maps[i].name, mainstone_maps[i].phys, 111 mainstone_maps[i].bankwidth * 8); 112 113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]); 114 115 if (!mymtds[i]) { 116 iounmap((void *)mainstone_maps[i].virt); 117 if (mainstone_maps[i].cached) 118 iounmap(mainstone_maps[i].cached); 119 if (!ret) 120 ret = -EIO; 121 continue; 122 } 123 mymtds[i]->owner = THIS_MODULE; 124 125 ret = parse_mtd_partitions(mymtds[i], probes, 126 &parsed_parts[i], 0); 127 128 if (ret > 0) 129 nr_parsed_parts[i] = ret; 130 } 131 132 if (!mymtds[0] && !mymtds[1]) 133 return ret; 134 135 for (i = 0; i < 2; i++) { 136 if (!mymtds[i]) { 137 printk(KERN_WARNING "%s is absent. Skipping\n", 138 mainstone_maps[i].name); 139 } else if (nr_parsed_parts[i]) { 140 add_mtd_partitions(mymtds[i], parsed_parts[i], 141 nr_parsed_parts[i]); 142 } else if (!i) { 143 printk("Using static partitions on %s\n", 144 mainstone_maps[i].name); 145 add_mtd_partitions(mymtds[i], mainstone_partitions, 146 ARRAY_SIZE(mainstone_partitions)); 147 } else { 148 printk("Registering %s as whole device\n", 149 mainstone_maps[i].name); 150 add_mtd_device(mymtds[i]); 151 } 152 } 153 return 0; 154} 155 156static void __exit cleanup_mainstone(void) 157{ 158 int i; 159 for (i = 0; i < 2; i++) { 160 if (!mymtds[i]) 161 continue; 162 163 if (nr_parsed_parts[i] || !i) 164 del_mtd_partitions(mymtds[i]); 165 else 166 del_mtd_device(mymtds[i]); 167 168 map_destroy(mymtds[i]); 169 iounmap((void *)mainstone_maps[i].virt); 170 if (mainstone_maps[i].cached) 171 iounmap(mainstone_maps[i].cached); 172 kfree(parsed_parts[i]); 173 } 174} 175 176module_init(init_mainstone); 177module_exit(cleanup_mainstone); 178 179MODULE_LICENSE("GPL"); 180MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>"); 181MODULE_DESCRIPTION("MTD map driver for Intel Mainstone"); 182