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 230 lines 5.4 kB view raw
1/* linux/drivers/mtd/maps/bast_flash.c 2 * 3 * Copyright (c) 2004-2005 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * Simtec Bast (EB2410ITX) NOR MTD Mapping driver 7 * 8 * Changelog: 9 * 20-Sep-2004 BJD Initial version 10 * 17-Jan-2005 BJD Add whole device if no partitions found 11 * 12 * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $ 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, write to the Free Software 26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27*/ 28 29#include <linux/module.h> 30#include <linux/types.h> 31#include <linux/init.h> 32#include <linux/kernel.h> 33#include <linux/string.h> 34#include <linux/ioport.h> 35#include <linux/device.h> 36 37#include <linux/mtd/mtd.h> 38#include <linux/mtd/map.h> 39#include <linux/mtd/partitions.h> 40 41#include <asm/io.h> 42#include <asm/mach-types.h> 43#include <asm/mach/flash.h> 44 45#include <asm/arch/map.h> 46#include <asm/arch/bast-map.h> 47#include <asm/arch/bast-cpld.h> 48 49#ifdef CONFIG_MTD_BAST_MAXSIZE 50#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M) 51#else 52#define AREA_MAXSIZE (32 * SZ_1M) 53#endif 54 55#define PFX "bast-flash: " 56 57struct bast_flash_info { 58 struct mtd_info *mtd; 59 struct map_info map; 60 struct mtd_partition *partitions; 61 struct resource *area; 62}; 63 64static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 65 66static struct bast_flash_info *to_bast_info(struct device *dev) 67{ 68 return (struct bast_flash_info *)dev_get_drvdata(dev); 69} 70 71static void bast_flash_setrw(int to) 72{ 73 unsigned int val; 74 unsigned long flags; 75 76 local_irq_save(flags); 77 val = __raw_readb(BAST_VA_CTRL3); 78 79 if (to) 80 val |= BAST_CPLD_CTRL3_ROMWEN; 81 else 82 val &= ~BAST_CPLD_CTRL3_ROMWEN; 83 84 pr_debug("new cpld ctrl3=%02x\n", val); 85 86 __raw_writeb(val, BAST_VA_CTRL3); 87 local_irq_restore(flags); 88} 89 90static int bast_flash_remove(struct device *dev) 91{ 92 struct bast_flash_info *info = to_bast_info(dev); 93 94 dev_set_drvdata(dev, NULL); 95 96 if (info == NULL) 97 return 0; 98 99 if (info->map.virt != NULL) 100 iounmap(info->map.virt); 101 102 if (info->mtd) { 103 del_mtd_partitions(info->mtd); 104 map_destroy(info->mtd); 105 } 106 107 if (info->partitions) 108 kfree(info->partitions); 109 110 if (info->area) { 111 release_resource(info->area); 112 kfree(info->area); 113 } 114 115 kfree(info); 116 117 return 0; 118} 119 120static int bast_flash_probe(struct device *dev) 121{ 122 struct platform_device *pdev = to_platform_device(dev); 123 struct bast_flash_info *info; 124 struct resource *res; 125 int err = 0; 126 127 info = kmalloc(sizeof(*info), GFP_KERNEL); 128 if (info == NULL) { 129 printk(KERN_ERR PFX "no memory for flash info\n"); 130 err = -ENOMEM; 131 goto exit_error; 132 } 133 134 memzero(info, sizeof(*info)); 135 dev_set_drvdata(dev, info); 136 137 res = pdev->resource; /* assume that the flash has one resource */ 138 139 info->map.phys = res->start; 140 info->map.size = res->end - res->start + 1; 141 info->map.name = dev->bus_id; 142 info->map.bankwidth = 2; 143 144 if (info->map.size > AREA_MAXSIZE) 145 info->map.size = AREA_MAXSIZE; 146 147 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, 148 info->map.phys, info->map.size); 149 150 info->area = request_mem_region(res->start, info->map.size, 151 pdev->name); 152 if (info->area == NULL) { 153 printk(KERN_ERR PFX "cannot reserve flash memory region\n"); 154 err = -ENOENT; 155 goto exit_error; 156 } 157 158 info->map.virt = ioremap(res->start, info->map.size); 159 pr_debug("%s: virt at %08x\n", __FUNCTION__, (int)info->map.virt); 160 161 if (info->map.virt == 0) { 162 printk(KERN_ERR PFX "failed to ioremap() region\n"); 163 err = -EIO; 164 goto exit_error; 165 } 166 167 simple_map_init(&info->map); 168 169 /* enable the write to the flash area */ 170 171 bast_flash_setrw(1); 172 173 /* probe for the device(s) */ 174 175 info->mtd = do_map_probe("jedec_probe", &info->map); 176 if (info->mtd == NULL) 177 info->mtd = do_map_probe("cfi_probe", &info->map); 178 179 if (info->mtd == NULL) { 180 printk(KERN_ERR PFX "map_probe() failed\n"); 181 err = -ENXIO; 182 goto exit_error; 183 } 184 185 /* mark ourselves as the owner */ 186 info->mtd->owner = THIS_MODULE; 187 188 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); 189 if (err > 0) { 190 err = add_mtd_partitions(info->mtd, info->partitions, err); 191 if (err) 192 printk(KERN_ERR PFX "cannot add/parse partitions\n"); 193 } else { 194 err = add_mtd_device(info->mtd); 195 } 196 197 if (err == 0) 198 return 0; 199 200 /* fall through to exit error */ 201 202 exit_error: 203 bast_flash_remove(dev); 204 return err; 205} 206 207static struct device_driver bast_flash_driver = { 208 .name = "bast-nor", 209 .bus = &platform_bus_type, 210 .probe = bast_flash_probe, 211 .remove = bast_flash_remove, 212}; 213 214static int __init bast_flash_init(void) 215{ 216 printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n"); 217 return driver_register(&bast_flash_driver); 218} 219 220static void __exit bast_flash_exit(void) 221{ 222 driver_unregister(&bast_flash_driver); 223} 224 225module_init(bast_flash_init); 226module_exit(bast_flash_exit); 227 228MODULE_LICENSE("GPL"); 229MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 230MODULE_DESCRIPTION("BAST MTD Map driver");