1 /* linux/drivers/mtd/maps/bast-flash.c
 
   3  * Copyright (c) 2004-2005 Simtec Electronics
 
   4  *      Ben Dooks <ben@simtec.co.uk>
 
   6  * Simtec Bast (EB2410ITX) NOR MTD Mapping driver
 
   9  *      20-Sep-2004  BJD  Initial version
 
  10  *      17-Jan-2005  BJD  Add whole device if no partitions found
 
  12  * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
 
  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.
 
  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.
 
  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
 
  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 #include <linux/slab.h>
 
  37 #include <linux/platform_device.h>
 
  38 #include <linux/mtd/mtd.h>
 
  39 #include <linux/mtd/map.h>
 
  40 #include <linux/mtd/partitions.h>
 
  43 #include <asm/mach/flash.h>
 
  45 #include <asm/arch/map.h>
 
  46 #include <asm/arch/bast-map.h>
 
  47 #include <asm/arch/bast-cpld.h>
 
  49 #ifdef CONFIG_MTD_BAST_MAXSIZE
 
  50 #define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M)
 
  52 #define AREA_MAXSIZE (32 * SZ_1M)
 
  55 #define PFX "bast-flash: "
 
  57 struct bast_flash_info {
 
  60         struct mtd_partition    *partitions;
 
  61         struct resource         *area;
 
  64 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
  66 static void bast_flash_setrw(int to)
 
  71         local_irq_save(flags);
 
  72         val = __raw_readb(BAST_VA_CTRL3);
 
  75                 val |= BAST_CPLD_CTRL3_ROMWEN;
 
  77                 val &= ~BAST_CPLD_CTRL3_ROMWEN;
 
  79         pr_debug("new cpld ctrl3=%02x\n", val);
 
  81         __raw_writeb(val, BAST_VA_CTRL3);
 
  82         local_irq_restore(flags);
 
  85 static int bast_flash_remove(struct platform_device *pdev)
 
  87         struct bast_flash_info *info = platform_get_drvdata(pdev);
 
  89         platform_set_drvdata(pdev, NULL);
 
  94         if (info->map.virt != NULL)
 
  95                 iounmap(info->map.virt);
 
  98                 del_mtd_partitions(info->mtd);
 
  99                 map_destroy(info->mtd);
 
 102         kfree(info->partitions);
 
 105                 release_resource(info->area);
 
 114 static int bast_flash_probe(struct platform_device *pdev)
 
 116         struct bast_flash_info *info;
 
 117         struct resource *res;
 
 120         info = kmalloc(sizeof(*info), GFP_KERNEL);
 
 122                 printk(KERN_ERR PFX "no memory for flash info\n");
 
 127         memzero(info, sizeof(*info));
 
 128         platform_set_drvdata(pdev, info);
 
 130         res = pdev->resource;  /* assume that the flash has one resource */
 
 132         info->map.phys = res->start;
 
 133         info->map.size = res->end - res->start + 1;
 
 134         info->map.name = pdev->dev.bus_id;
 
 135         info->map.bankwidth = 2;
 
 137         if (info->map.size > AREA_MAXSIZE)
 
 138                 info->map.size = AREA_MAXSIZE;
 
 140         pr_debug("%s: area %08lx, size %ld\n", __func__,
 
 141                  info->map.phys, info->map.size);
 
 143         info->area = request_mem_region(res->start, info->map.size,
 
 145         if (info->area == NULL) {
 
 146                 printk(KERN_ERR PFX "cannot reserve flash memory region\n");
 
 151         info->map.virt = ioremap(res->start, info->map.size);
 
 152         pr_debug("%s: virt at %08x\n", __func__, (int)info->map.virt);
 
 154         if (info->map.virt == 0) {
 
 155                 printk(KERN_ERR PFX "failed to ioremap() region\n");
 
 160         simple_map_init(&info->map);
 
 162         /* enable the write to the flash area */
 
 166         /* probe for the device(s) */
 
 168         info->mtd = do_map_probe("jedec_probe", &info->map);
 
 169         if (info->mtd == NULL)
 
 170                 info->mtd = do_map_probe("cfi_probe", &info->map);
 
 172         if (info->mtd == NULL) {
 
 173                 printk(KERN_ERR PFX "map_probe() failed\n");
 
 178         /* mark ourselves as the owner */
 
 179         info->mtd->owner = THIS_MODULE;
 
 181         err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
 
 183                 err = add_mtd_partitions(info->mtd, info->partitions, err);
 
 185                         printk(KERN_ERR PFX "cannot add/parse partitions\n");
 
 187                 err = add_mtd_device(info->mtd);
 
 193         /* fall through to exit error */
 
 196         bast_flash_remove(pdev);
 
 200 static struct platform_driver bast_flash_driver = {
 
 201         .probe          = bast_flash_probe,
 
 202         .remove         = bast_flash_remove,
 
 205                 .owner  = THIS_MODULE,
 
 209 static int __init bast_flash_init(void)
 
 211         printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n");
 
 212         return platform_driver_register(&bast_flash_driver);
 
 215 static void __exit bast_flash_exit(void)
 
 217         platform_driver_unregister(&bast_flash_driver);
 
 220 module_init(bast_flash_init);
 
 221 module_exit(bast_flash_exit);
 
 223 MODULE_LICENSE("GPL");
 
 224 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 
 225 MODULE_DESCRIPTION("BAST MTD Map driver");
 
 226 MODULE_ALIAS("platform:bast-nor");