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 v2.6.18-rc4 213 lines 5.0 kB view raw
1/*====================================================================== 2 3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver 4 5 Copyright (C) 2000 ARM Limited 6 Copyright (C) 2003 Deep Blue Solutions Ltd. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 This is access code for flashes using ARM's flash partitioning 23 standards. 24 25 $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $ 26 27======================================================================*/ 28 29#include <linux/module.h> 30#include <linux/types.h> 31#include <linux/kernel.h> 32#include <linux/slab.h> 33#include <linux/ioport.h> 34#include <linux/platform_device.h> 35#include <linux/init.h> 36 37#include <linux/mtd/mtd.h> 38#include <linux/mtd/map.h> 39#include <linux/mtd/partitions.h> 40 41#include <asm/mach/flash.h> 42#include <asm/hardware.h> 43#include <asm/io.h> 44#include <asm/system.h> 45 46#ifdef CONFIG_ARCH_P720T 47#define FLASH_BASE (0x04000000) 48#define FLASH_SIZE (64*1024*1024) 49#endif 50 51struct armflash_info { 52 struct flash_platform_data *plat; 53 struct resource *res; 54 struct mtd_partition *parts; 55 struct mtd_info *mtd; 56 struct map_info map; 57}; 58 59static void armflash_set_vpp(struct map_info *map, int on) 60{ 61 struct armflash_info *info = container_of(map, struct armflash_info, map); 62 63 if (info->plat && info->plat->set_vpp) 64 info->plat->set_vpp(on); 65} 66 67static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; 68 69static int armflash_probe(struct platform_device *dev) 70{ 71 struct flash_platform_data *plat = dev->dev.platform_data; 72 struct resource *res = dev->resource; 73 unsigned int size = res->end - res->start + 1; 74 struct armflash_info *info; 75 int err; 76 void __iomem *base; 77 78 info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL); 79 if (!info) { 80 err = -ENOMEM; 81 goto out; 82 } 83 84 memset(info, 0, sizeof(struct armflash_info)); 85 86 info->plat = plat; 87 if (plat && plat->init) { 88 err = plat->init(); 89 if (err) 90 goto no_resource; 91 } 92 93 info->res = request_mem_region(res->start, size, "armflash"); 94 if (!info->res) { 95 err = -EBUSY; 96 goto no_resource; 97 } 98 99 base = ioremap(res->start, size); 100 if (!base) { 101 err = -ENOMEM; 102 goto no_mem; 103 } 104 105 /* 106 * look for CFI based flash parts fitted to this board 107 */ 108 info->map.size = size; 109 info->map.bankwidth = plat->width; 110 info->map.phys = res->start; 111 info->map.virt = base; 112 info->map.name = dev->dev.bus_id; 113 info->map.set_vpp = armflash_set_vpp; 114 115 simple_map_init(&info->map); 116 117 /* 118 * Also, the CFI layer automatically works out what size 119 * of chips we have, and does the necessary identification 120 * for us automatically. 121 */ 122 info->mtd = do_map_probe(plat->map_name, &info->map); 123 if (!info->mtd) { 124 err = -ENXIO; 125 goto no_device; 126 } 127 128 info->mtd->owner = THIS_MODULE; 129 130 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); 131 if (err > 0) { 132 err = add_mtd_partitions(info->mtd, info->parts, err); 133 if (err) 134 printk(KERN_ERR 135 "mtd partition registration failed: %d\n", err); 136 } 137 138 if (err == 0) 139 platform_set_drvdata(dev, info); 140 141 /* 142 * If we got an error, free all resources. 143 */ 144 if (err < 0) { 145 if (info->mtd) { 146 del_mtd_partitions(info->mtd); 147 map_destroy(info->mtd); 148 } 149 kfree(info->parts); 150 151 no_device: 152 iounmap(base); 153 no_mem: 154 release_mem_region(res->start, size); 155 no_resource: 156 if (plat && plat->exit) 157 plat->exit(); 158 kfree(info); 159 } 160 out: 161 return err; 162} 163 164static int armflash_remove(struct platform_device *dev) 165{ 166 struct armflash_info *info = platform_get_drvdata(dev); 167 168 platform_set_drvdata(dev, NULL); 169 170 if (info) { 171 if (info->mtd) { 172 del_mtd_partitions(info->mtd); 173 map_destroy(info->mtd); 174 } 175 kfree(info->parts); 176 177 iounmap(info->map.virt); 178 release_resource(info->res); 179 kfree(info->res); 180 181 if (info->plat && info->plat->exit) 182 info->plat->exit(); 183 184 kfree(info); 185 } 186 187 return 0; 188} 189 190static struct platform_driver armflash_driver = { 191 .probe = armflash_probe, 192 .remove = armflash_remove, 193 .driver = { 194 .name = "armflash", 195 }, 196}; 197 198static int __init armflash_init(void) 199{ 200 return platform_driver_register(&armflash_driver); 201} 202 203static void __exit armflash_exit(void) 204{ 205 platform_driver_unregister(&armflash_driver); 206} 207 208module_init(armflash_init); 209module_exit(armflash_exit); 210 211MODULE_AUTHOR("ARM Ltd"); 212MODULE_DESCRIPTION("ARM Integrator CFI map driver"); 213MODULE_LICENSE("GPL");