1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Handle mapping of the NOR flash on implementa A7 boards 4 * 5 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 */ 7 8 #include <linux/module.h> 9 #include <linux/types.h> 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <asm/io.h> 13 #include <linux/mtd/mtd.h> 14 #include <linux/mtd/map.h> 15 #include <linux/mtd/partitions.h> 16 17 #define WINDOW_ADDR0 0x00000000 /* physical properties of flash */ 18 #define WINDOW_SIZE0 0x00800000 19 #define WINDOW_ADDR1 0x10000000 /* physical properties of flash */ 20 #define WINDOW_SIZE1 0x00800000 21 #define NUM_FLASHBANKS 2 22 #define BUSWIDTH 4 23 24 #define MSG_PREFIX "impA7:" /* prefix for our printk()'s */ 25 #define MTDID "impa7-%d" /* for mtdparts= partitioning */ 26 27 static struct mtd_info *impa7_mtd[NUM_FLASHBANKS]; 28 29 static const char * const rom_probe_types[] = { "jedec_probe", NULL }; 30 31 static struct map_info impa7_map[NUM_FLASHBANKS] = { 32 { 33 .name = "impA7 NOR Flash Bank #0", 34 .size = WINDOW_SIZE0, 35 .bankwidth = BUSWIDTH, 36 }, 37 { 38 .name = "impA7 NOR Flash Bank #1", 39 .size = WINDOW_SIZE1, 40 .bankwidth = BUSWIDTH, 41 }, 42 }; 43 44 /* 45 * MTD partitioning stuff 46 */ 47 static const struct mtd_partition partitions[] = 48 { 49 { 50 .name = "FileSystem", 51 .size = 0x800000, 52 .offset = 0x00000000 53 }, 54 }; 55 56 static int __init init_impa7(void) 57 { 58 const char * const *type; 59 int i; 60 static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = { 61 { WINDOW_ADDR0, WINDOW_SIZE0 }, 62 { WINDOW_ADDR1, WINDOW_SIZE1 }, 63 }; 64 int devicesfound = 0; 65 66 for(i=0; i<NUM_FLASHBANKS; i++) 67 { 68 printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n", 69 pt[i].size, pt[i].addr); 70 71 impa7_map[i].phys = pt[i].addr; 72 impa7_map[i].virt = ioremap(pt[i].addr, pt[i].size); 73 if (!impa7_map[i].virt) { 74 printk(MSG_PREFIX "failed to ioremap\n"); 75 return -EIO; 76 } 77 simple_map_init(&impa7_map[i]); 78 79 impa7_mtd[i] = NULL; 80 type = rom_probe_types; 81 for(; !impa7_mtd[i] && *type; type++) { 82 impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]); 83 } 84 85 if (impa7_mtd[i]) { 86 impa7_mtd[i]->owner = THIS_MODULE; 87 devicesfound++; 88 mtd_device_register(impa7_mtd[i], partitions, 89 ARRAY_SIZE(partitions)); 90 } else { 91 iounmap((void __iomem *)impa7_map[i].virt); 92 } 93 } 94 return devicesfound == 0 ? -ENXIO : 0; 95 } 96 97 static void __exit cleanup_impa7(void) 98 { 99 int i; 100 for (i=0; i<NUM_FLASHBANKS; i++) { 101 if (impa7_mtd[i]) { 102 mtd_device_unregister(impa7_mtd[i]); 103 map_destroy(impa7_mtd[i]); 104 iounmap((void __iomem *)impa7_map[i].virt); 105 impa7_map[i].virt = NULL; 106 } 107 } 108 } 109 110 module_init(init_impa7); 111 module_exit(cleanup_impa7); 112 113 MODULE_LICENSE("GPL"); 114 MODULE_AUTHOR("Pavel Bartusek <pba@sysgo.de>"); 115 MODULE_DESCRIPTION("MTD map driver for implementa impA7"); 116