Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 168 lines 4.4 kB view raw
1/* 2 * $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $ 3 * 4 * Map driver for the Lubbock 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/mtd/mtd.h> 20#include <linux/mtd/map.h> 21#include <linux/mtd/partitions.h> 22#include <asm/io.h> 23#include <asm/hardware.h> 24#include <asm/arch/pxa-regs.h> 25#include <asm/arch/lubbock.h> 26 27 28#define ROM_ADDR 0x00000000 29#define FLASH_ADDR 0x04000000 30 31#define WINDOW_SIZE 64*1024*1024 32 33static void lubbock_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len) 34{ 35 consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE); 36} 37 38static struct map_info lubbock_maps[2] = { { 39 .size = WINDOW_SIZE, 40 .phys = 0x00000000, 41 .inval_cache = lubbock_map_inval_cache, 42}, { 43 .size = WINDOW_SIZE, 44 .phys = 0x04000000, 45 .inval_cache = lubbock_map_inval_cache, 46} }; 47 48static struct mtd_partition lubbock_partitions[] = { 49 { 50 .name = "Bootloader", 51 .size = 0x00040000, 52 .offset = 0, 53 .mask_flags = MTD_WRITEABLE /* force read-only */ 54 },{ 55 .name = "Kernel", 56 .size = 0x00100000, 57 .offset = 0x00040000, 58 },{ 59 .name = "Filesystem", 60 .size = MTDPART_SIZ_FULL, 61 .offset = 0x00140000 62 } 63}; 64 65static struct mtd_info *mymtds[2]; 66static struct mtd_partition *parsed_parts[2]; 67static int nr_parsed_parts[2]; 68 69static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 70 71static int __init init_lubbock(void) 72{ 73 int flashboot = (LUB_CONF_SWITCHES & 1); 74 int ret = 0, i; 75 76 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth = 77 (BOOT_DEF & 1) ? 2 : 4; 78 79 /* Compensate for the nROMBT switch which swaps the flash banks */ 80 printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", 81 flashboot?"Flash":"ROM", flashboot); 82 83 lubbock_maps[flashboot^1].name = "Lubbock Application Flash"; 84 lubbock_maps[flashboot].name = "Lubbock Boot ROM"; 85 86 for (i = 0; i < 2; i++) { 87 lubbock_maps[i].virt = ioremap(lubbock_maps[i].phys, WINDOW_SIZE); 88 if (!lubbock_maps[i].virt) { 89 printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name); 90 if (!ret) 91 ret = -ENOMEM; 92 continue; 93 } 94 lubbock_maps[i].cached = ioremap_cached(lubbock_maps[i].phys, WINDOW_SIZE); 95 if (!lubbock_maps[i].cached) 96 printk(KERN_WARNING "Failed to ioremap cached %s\n", lubbock_maps[i].name); 97 simple_map_init(&lubbock_maps[i]); 98 99 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", 100 lubbock_maps[i].name, lubbock_maps[i].phys, 101 lubbock_maps[i].bankwidth * 8); 102 103 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); 104 105 if (!mymtds[i]) { 106 iounmap((void *)lubbock_maps[i].virt); 107 if (lubbock_maps[i].cached) 108 iounmap(lubbock_maps[i].cached); 109 if (!ret) 110 ret = -EIO; 111 continue; 112 } 113 mymtds[i]->owner = THIS_MODULE; 114 115 ret = parse_mtd_partitions(mymtds[i], probes, 116 &parsed_parts[i], 0); 117 118 if (ret > 0) 119 nr_parsed_parts[i] = ret; 120 } 121 122 if (!mymtds[0] && !mymtds[1]) 123 return ret; 124 125 for (i = 0; i < 2; i++) { 126 if (!mymtds[i]) { 127 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); 128 } else if (nr_parsed_parts[i]) { 129 add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); 130 } else if (!i) { 131 printk("Using static partitions on %s\n", lubbock_maps[i].name); 132 add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions)); 133 } else { 134 printk("Registering %s as whole device\n", lubbock_maps[i].name); 135 add_mtd_device(mymtds[i]); 136 } 137 } 138 return 0; 139} 140 141static void __exit cleanup_lubbock(void) 142{ 143 int i; 144 for (i = 0; i < 2; i++) { 145 if (!mymtds[i]) 146 continue; 147 148 if (nr_parsed_parts[i] || !i) 149 del_mtd_partitions(mymtds[i]); 150 else 151 del_mtd_device(mymtds[i]); 152 153 map_destroy(mymtds[i]); 154 iounmap((void *)lubbock_maps[i].virt); 155 if (lubbock_maps[i].cached) 156 iounmap(lubbock_maps[i].cached); 157 158 if (parsed_parts[i]) 159 kfree(parsed_parts[i]); 160 } 161} 162 163module_init(init_lubbock); 164module_exit(cleanup_lubbock); 165 166MODULE_LICENSE("GPL"); 167MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>"); 168MODULE_DESCRIPTION("MTD map driver for Intel Lubbock");