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.30-rc8 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======================================================================*/ 26 27#include <linux/module.h> 28#include <linux/types.h> 29#include <linux/kernel.h> 30#include <linux/slab.h> 31#include <linux/ioport.h> 32#include <linux/platform_device.h> 33#include <linux/init.h> 34#include <linux/io.h> 35 36#include <linux/mtd/mtd.h> 37#include <linux/mtd/map.h> 38#include <linux/mtd/partitions.h> 39 40#include <asm/mach/flash.h> 41#include <mach/hardware.h> 42#include <asm/system.h> 43 44#ifdef CONFIG_ARCH_P720T 45#define FLASH_BASE (0x04000000) 46#define FLASH_SIZE (64*1024*1024) 47#endif 48 49struct armflash_info { 50 struct flash_platform_data *plat; 51 struct resource *res; 52 struct mtd_partition *parts; 53 struct mtd_info *mtd; 54 struct map_info map; 55}; 56 57static void armflash_set_vpp(struct map_info *map, int on) 58{ 59 struct armflash_info *info = container_of(map, struct armflash_info, map); 60 61 if (info->plat && info->plat->set_vpp) 62 info->plat->set_vpp(on); 63} 64 65static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; 66 67static int armflash_probe(struct platform_device *dev) 68{ 69 struct flash_platform_data *plat = dev->dev.platform_data; 70 struct resource *res = dev->resource; 71 unsigned int size = res->end - res->start + 1; 72 struct armflash_info *info; 73 int err; 74 void __iomem *base; 75 76 info = kzalloc(sizeof(struct armflash_info), GFP_KERNEL); 77 if (!info) { 78 err = -ENOMEM; 79 goto out; 80 } 81 82 info->plat = plat; 83 if (plat && plat->init) { 84 err = plat->init(); 85 if (err) 86 goto no_resource; 87 } 88 89 info->res = request_mem_region(res->start, size, "armflash"); 90 if (!info->res) { 91 err = -EBUSY; 92 goto no_resource; 93 } 94 95 base = ioremap(res->start, size); 96 if (!base) { 97 err = -ENOMEM; 98 goto no_mem; 99 } 100 101 /* 102 * look for CFI based flash parts fitted to this board 103 */ 104 info->map.size = size; 105 info->map.bankwidth = plat->width; 106 info->map.phys = res->start; 107 info->map.virt = base; 108 info->map.name = dev_name(&dev->dev); 109 info->map.set_vpp = armflash_set_vpp; 110 111 simple_map_init(&info->map); 112 113 /* 114 * Also, the CFI layer automatically works out what size 115 * of chips we have, and does the necessary identification 116 * for us automatically. 117 */ 118 info->mtd = do_map_probe(plat->map_name, &info->map); 119 if (!info->mtd) { 120 err = -ENXIO; 121 goto no_device; 122 } 123 124 info->mtd->owner = THIS_MODULE; 125 126 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); 127 if (err > 0) { 128 err = add_mtd_partitions(info->mtd, info->parts, err); 129 if (err) 130 printk(KERN_ERR 131 "mtd partition registration failed: %d\n", err); 132 } 133 134 if (err == 0) 135 platform_set_drvdata(dev, info); 136 137 /* 138 * If we got an error, free all resources. 139 */ 140 if (err < 0) { 141 if (info->mtd) { 142 del_mtd_partitions(info->mtd); 143 map_destroy(info->mtd); 144 } 145 kfree(info->parts); 146 147 no_device: 148 iounmap(base); 149 no_mem: 150 release_mem_region(res->start, size); 151 no_resource: 152 if (plat && plat->exit) 153 plat->exit(); 154 kfree(info); 155 } 156 out: 157 return err; 158} 159 160static int armflash_remove(struct platform_device *dev) 161{ 162 struct armflash_info *info = platform_get_drvdata(dev); 163 164 platform_set_drvdata(dev, NULL); 165 166 if (info) { 167 if (info->mtd) { 168 del_mtd_partitions(info->mtd); 169 map_destroy(info->mtd); 170 } 171 kfree(info->parts); 172 173 iounmap(info->map.virt); 174 release_resource(info->res); 175 kfree(info->res); 176 177 if (info->plat && info->plat->exit) 178 info->plat->exit(); 179 180 kfree(info); 181 } 182 183 return 0; 184} 185 186static struct platform_driver armflash_driver = { 187 .probe = armflash_probe, 188 .remove = armflash_remove, 189 .driver = { 190 .name = "armflash", 191 .owner = THIS_MODULE, 192 }, 193}; 194 195static int __init armflash_init(void) 196{ 197 return platform_driver_register(&armflash_driver); 198} 199 200static void __exit armflash_exit(void) 201{ 202 platform_driver_unregister(&armflash_driver); 203} 204 205module_init(armflash_init); 206module_exit(armflash_exit); 207 208MODULE_AUTHOR("ARM Ltd"); 209MODULE_DESCRIPTION("ARM Integrator CFI map driver"); 210MODULE_LICENSE("GPL"); 211MODULE_ALIAS("platform:armflash");