11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Handle mapping of the NOR flash on implementa A7 boards 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright 2002 SYSGO Real-Time Solutions GmbH 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4SLinus Torvalds * it under the terms of the GNU General Public License version 2 as 81da177e4SLinus Torvalds * published by the Free Software Foundation. 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/module.h> 121da177e4SLinus Torvalds #include <linux/types.h> 131da177e4SLinus Torvalds #include <linux/kernel.h> 141da177e4SLinus Torvalds #include <linux/init.h> 151da177e4SLinus Torvalds #include <asm/io.h> 161da177e4SLinus Torvalds #include <linux/mtd/mtd.h> 171da177e4SLinus Torvalds #include <linux/mtd/map.h> 181da177e4SLinus Torvalds #include <linux/mtd/partitions.h> 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds #define WINDOW_ADDR0 0x00000000 /* physical properties of flash */ 211da177e4SLinus Torvalds #define WINDOW_SIZE0 0x00800000 221da177e4SLinus Torvalds #define WINDOW_ADDR1 0x10000000 /* physical properties of flash */ 231da177e4SLinus Torvalds #define WINDOW_SIZE1 0x00800000 241da177e4SLinus Torvalds #define NUM_FLASHBANKS 2 251da177e4SLinus Torvalds #define BUSWIDTH 4 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds /* can be { "cfi_probe", "jedec_probe", "map_rom", NULL } */ 281da177e4SLinus Torvalds #define PROBETYPES { "jedec_probe", NULL } 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds #define MSG_PREFIX "impA7:" /* prefix for our printk()'s */ 311da177e4SLinus Torvalds #define MTDID "impa7-%d" /* for mtdparts= partitioning */ 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds static struct mtd_info *impa7_mtd[NUM_FLASHBANKS]; 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds static struct map_info impa7_map[NUM_FLASHBANKS] = { 371da177e4SLinus Torvalds { 381da177e4SLinus Torvalds .name = "impA7 NOR Flash Bank #0", 391da177e4SLinus Torvalds .size = WINDOW_SIZE0, 401da177e4SLinus Torvalds .bankwidth = BUSWIDTH, 411da177e4SLinus Torvalds }, 421da177e4SLinus Torvalds { 431da177e4SLinus Torvalds .name = "impA7 NOR Flash Bank #1", 441da177e4SLinus Torvalds .size = WINDOW_SIZE1, 451da177e4SLinus Torvalds .bankwidth = BUSWIDTH, 461da177e4SLinus Torvalds }, 471da177e4SLinus Torvalds }; 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* 501da177e4SLinus Torvalds * MTD partitioning stuff 511da177e4SLinus Torvalds */ 525003403bSDmitry Eremin-Solenikov static struct mtd_partition partitions[] = 531da177e4SLinus Torvalds { 541da177e4SLinus Torvalds { 551da177e4SLinus Torvalds .name = "FileSystem", 561da177e4SLinus Torvalds .size = 0x800000, 571da177e4SLinus Torvalds .offset = 0x00000000 581da177e4SLinus Torvalds }, 591da177e4SLinus Torvalds }; 601da177e4SLinus Torvalds 614f8f3af2SDmitri Vorobiev static int __init init_impa7(void) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds static const char *rom_probe_types[] = PROBETYPES; 641da177e4SLinus Torvalds const char **type; 651da177e4SLinus Torvalds int i; 661da177e4SLinus Torvalds static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = { 671da177e4SLinus Torvalds { WINDOW_ADDR0, WINDOW_SIZE0 }, 681da177e4SLinus Torvalds { WINDOW_ADDR1, WINDOW_SIZE1 }, 691da177e4SLinus Torvalds }; 701da177e4SLinus Torvalds int devicesfound = 0; 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds for(i=0; i<NUM_FLASHBANKS; i++) 731da177e4SLinus Torvalds { 741da177e4SLinus Torvalds printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n", 751da177e4SLinus Torvalds pt[i].size, pt[i].addr); 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds impa7_map[i].phys = pt[i].addr; 781da177e4SLinus Torvalds impa7_map[i].virt = ioremap(pt[i].addr, pt[i].size); 791da177e4SLinus Torvalds if (!impa7_map[i].virt) { 801da177e4SLinus Torvalds printk(MSG_PREFIX "failed to ioremap\n"); 811da177e4SLinus Torvalds return -EIO; 821da177e4SLinus Torvalds } 831da177e4SLinus Torvalds simple_map_init(&impa7_map[i]); 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds impa7_mtd[i] = 0; 861da177e4SLinus Torvalds type = rom_probe_types; 871da177e4SLinus Torvalds for(; !impa7_mtd[i] && *type; type++) { 881da177e4SLinus Torvalds impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]); 891da177e4SLinus Torvalds } 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds if (impa7_mtd[i]) { 921da177e4SLinus Torvalds impa7_mtd[i]->owner = THIS_MODULE; 931da177e4SLinus Torvalds devicesfound++; 9442d7fbe2SArtem Bityutskiy mtd_device_parse_register(impa7_mtd[i], NULL, NULL, 955003403bSDmitry Eremin-Solenikov partitions, 965003403bSDmitry Eremin-Solenikov ARRAY_SIZE(partitions)); 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds else 991da177e4SLinus Torvalds iounmap((void *)impa7_map[i].virt); 1001da177e4SLinus Torvalds } 1011da177e4SLinus Torvalds return devicesfound == 0 ? -ENXIO : 0; 1021da177e4SLinus Torvalds } 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds static void __exit cleanup_impa7(void) 1051da177e4SLinus Torvalds { 1061da177e4SLinus Torvalds int i; 1071da177e4SLinus Torvalds for (i=0; i<NUM_FLASHBANKS; i++) { 1081da177e4SLinus Torvalds if (impa7_mtd[i]) { 10996b639fdSJamie Iles mtd_device_unregister(impa7_mtd[i]); 1101da177e4SLinus Torvalds map_destroy(impa7_mtd[i]); 1111da177e4SLinus Torvalds iounmap((void *)impa7_map[i].virt); 1121da177e4SLinus Torvalds impa7_map[i].virt = 0; 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds } 1151da177e4SLinus Torvalds } 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds module_init(init_impa7); 1181da177e4SLinus Torvalds module_exit(cleanup_impa7); 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 1211da177e4SLinus Torvalds MODULE_AUTHOR("Pavel Bartusek <pba@sysgo.de>"); 1221da177e4SLinus Torvalds MODULE_DESCRIPTION("MTD map driver for implementa impA7"); 123