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.20 211 lines 4.9 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 = kzalloc(sizeof(struct armflash_info), GFP_KERNEL); 79 if (!info) { 80 err = -ENOMEM; 81 goto out; 82 } 83 84 info->plat = plat; 85 if (plat && plat->init) { 86 err = plat->init(); 87 if (err) 88 goto no_resource; 89 } 90 91 info->res = request_mem_region(res->start, size, "armflash"); 92 if (!info->res) { 93 err = -EBUSY; 94 goto no_resource; 95 } 96 97 base = ioremap(res->start, size); 98 if (!base) { 99 err = -ENOMEM; 100 goto no_mem; 101 } 102 103 /* 104 * look for CFI based flash parts fitted to this board 105 */ 106 info->map.size = size; 107 info->map.bankwidth = plat->width; 108 info->map.phys = res->start; 109 info->map.virt = base; 110 info->map.name = dev->dev.bus_id; 111 info->map.set_vpp = armflash_set_vpp; 112 113 simple_map_init(&info->map); 114 115 /* 116 * Also, the CFI layer automatically works out what size 117 * of chips we have, and does the necessary identification 118 * for us automatically. 119 */ 120 info->mtd = do_map_probe(plat->map_name, &info->map); 121 if (!info->mtd) { 122 err = -ENXIO; 123 goto no_device; 124 } 125 126 info->mtd->owner = THIS_MODULE; 127 128 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); 129 if (err > 0) { 130 err = add_mtd_partitions(info->mtd, info->parts, err); 131 if (err) 132 printk(KERN_ERR 133 "mtd partition registration failed: %d\n", err); 134 } 135 136 if (err == 0) 137 platform_set_drvdata(dev, info); 138 139 /* 140 * If we got an error, free all resources. 141 */ 142 if (err < 0) { 143 if (info->mtd) { 144 del_mtd_partitions(info->mtd); 145 map_destroy(info->mtd); 146 } 147 kfree(info->parts); 148 149 no_device: 150 iounmap(base); 151 no_mem: 152 release_mem_region(res->start, size); 153 no_resource: 154 if (plat && plat->exit) 155 plat->exit(); 156 kfree(info); 157 } 158 out: 159 return err; 160} 161 162static int armflash_remove(struct platform_device *dev) 163{ 164 struct armflash_info *info = platform_get_drvdata(dev); 165 166 platform_set_drvdata(dev, NULL); 167 168 if (info) { 169 if (info->mtd) { 170 del_mtd_partitions(info->mtd); 171 map_destroy(info->mtd); 172 } 173 kfree(info->parts); 174 175 iounmap(info->map.virt); 176 release_resource(info->res); 177 kfree(info->res); 178 179 if (info->plat && info->plat->exit) 180 info->plat->exit(); 181 182 kfree(info); 183 } 184 185 return 0; 186} 187 188static struct platform_driver armflash_driver = { 189 .probe = armflash_probe, 190 .remove = armflash_remove, 191 .driver = { 192 .name = "armflash", 193 }, 194}; 195 196static int __init armflash_init(void) 197{ 198 return platform_driver_register(&armflash_driver); 199} 200 201static void __exit armflash_exit(void) 202{ 203 platform_driver_unregister(&armflash_driver); 204} 205 206module_init(armflash_init); 207module_exit(armflash_exit); 208 209MODULE_AUTHOR("ARM Ltd"); 210MODULE_DESCRIPTION("ARM Integrator CFI map driver"); 211MODULE_LICENSE("GPL");