| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Mapping for Ocotea user flash | 
|  | 3 | * | 
|  | 4 | * Matt Porter <mporter@kernel.crashing.org> | 
|  | 5 | * | 
|  | 6 | * Copyright 2002-2004 MontaVista Software Inc. | 
|  | 7 | * | 
|  | 8 | * This program is free software; you can redistribute  it and/or modify it | 
|  | 9 | * under  the terms of  the GNU General  Public License as published by the | 
|  | 10 | * Free Software Foundation;  either version 2 of the  License, or (at your | 
|  | 11 | * option) any later version. | 
|  | 12 | */ | 
|  | 13 |  | 
|  | 14 | #include <linux/module.h> | 
|  | 15 | #include <linux/types.h> | 
|  | 16 | #include <linux/kernel.h> | 
|  | 17 | #include <linux/init.h> | 
|  | 18 | #include <linux/mtd/mtd.h> | 
|  | 19 | #include <linux/mtd/map.h> | 
|  | 20 | #include <linux/mtd/partitions.h> | 
|  | 21 | #include <linux/config.h> | 
|  | 22 | #include <linux/version.h> | 
|  | 23 | #include <asm/io.h> | 
|  | 24 | #include <asm/ibm44x.h> | 
|  | 25 | #include <platforms/4xx/ocotea.h> | 
|  | 26 |  | 
|  | 27 | static struct mtd_info *flash; | 
|  | 28 |  | 
|  | 29 | static struct map_info ocotea_small_map = { | 
|  | 30 | .name =		"Ocotea small flash", | 
|  | 31 | .size =		OCOTEA_SMALL_FLASH_SIZE, | 
|  | 32 | .buswidth =	1, | 
|  | 33 | }; | 
|  | 34 |  | 
|  | 35 | static struct map_info ocotea_large_map = { | 
|  | 36 | .name =		"Ocotea large flash", | 
|  | 37 | .size =		OCOTEA_LARGE_FLASH_SIZE, | 
|  | 38 | .buswidth =	1, | 
|  | 39 | }; | 
|  | 40 |  | 
|  | 41 | static struct mtd_partition ocotea_small_partitions[] = { | 
|  | 42 | { | 
|  | 43 | .name =   "pibs", | 
|  | 44 | .offset = 0x0, | 
|  | 45 | .size =   0x100000, | 
|  | 46 | } | 
|  | 47 | }; | 
|  | 48 |  | 
|  | 49 | static struct mtd_partition ocotea_large_partitions[] = { | 
|  | 50 | { | 
|  | 51 | .name =   "fs", | 
|  | 52 | .offset = 0, | 
|  | 53 | .size =   0x300000, | 
|  | 54 | }, | 
|  | 55 | { | 
|  | 56 | .name =   "firmware", | 
|  | 57 | .offset = 0x300000, | 
|  | 58 | .size =   0x100000, | 
|  | 59 | } | 
|  | 60 | }; | 
|  | 61 |  | 
|  | 62 | #define NB_OF(x)  (sizeof(x)/sizeof(x[0])) | 
|  | 63 |  | 
|  | 64 | int __init init_ocotea(void) | 
|  | 65 | { | 
|  | 66 | u8 fpga0_reg; | 
|  | 67 | u8 *fpga0_adr; | 
|  | 68 | unsigned long long small_flash_base, large_flash_base; | 
|  | 69 |  | 
|  | 70 | fpga0_adr = ioremap64(OCOTEA_FPGA_ADDR, 16); | 
|  | 71 | if (!fpga0_adr) | 
|  | 72 | return -ENOMEM; | 
|  | 73 |  | 
|  | 74 | fpga0_reg = readb((unsigned long)fpga0_adr); | 
|  | 75 | iounmap(fpga0_adr); | 
|  | 76 |  | 
|  | 77 | if (OCOTEA_BOOT_LARGE_FLASH(fpga0_reg)) { | 
|  | 78 | small_flash_base = OCOTEA_SMALL_FLASH_HIGH; | 
|  | 79 | large_flash_base = OCOTEA_LARGE_FLASH_LOW; | 
|  | 80 | } | 
|  | 81 | else { | 
|  | 82 | small_flash_base = OCOTEA_SMALL_FLASH_LOW; | 
|  | 83 | large_flash_base = OCOTEA_LARGE_FLASH_HIGH; | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | ocotea_small_map.phys = small_flash_base; | 
|  | 87 | ocotea_small_map.virt = ioremap64(small_flash_base, | 
|  | 88 | ocotea_small_map.size); | 
|  | 89 |  | 
|  | 90 | if (!ocotea_small_map.virt) { | 
|  | 91 | printk("Failed to ioremap flash\n"); | 
|  | 92 | return -EIO; | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | simple_map_init(&ocotea_small_map); | 
|  | 96 |  | 
|  | 97 | flash = do_map_probe("map_rom", &ocotea_small_map); | 
|  | 98 | if (flash) { | 
|  | 99 | flash->owner = THIS_MODULE; | 
|  | 100 | add_mtd_partitions(flash, ocotea_small_partitions, | 
|  | 101 | NB_OF(ocotea_small_partitions)); | 
|  | 102 | } else { | 
|  | 103 | printk("map probe failed for flash\n"); | 
|  | 104 | return -ENXIO; | 
|  | 105 | } | 
|  | 106 |  | 
|  | 107 | ocotea_large_map.phys = large_flash_base; | 
|  | 108 | ocotea_large_map.virt = ioremap64(large_flash_base, | 
|  | 109 | ocotea_large_map.size); | 
|  | 110 |  | 
|  | 111 | if (!ocotea_large_map.virt) { | 
|  | 112 | printk("Failed to ioremap flash\n"); | 
|  | 113 | return -EIO; | 
|  | 114 | } | 
|  | 115 |  | 
|  | 116 | simple_map_init(&ocotea_large_map); | 
|  | 117 |  | 
|  | 118 | flash = do_map_probe("cfi_probe", &ocotea_large_map); | 
|  | 119 | if (flash) { | 
|  | 120 | flash->owner = THIS_MODULE; | 
|  | 121 | add_mtd_partitions(flash, ocotea_large_partitions, | 
|  | 122 | NB_OF(ocotea_large_partitions)); | 
|  | 123 | } else { | 
|  | 124 | printk("map probe failed for flash\n"); | 
|  | 125 | return -ENXIO; | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | return 0; | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | static void __exit cleanup_ocotea(void) | 
|  | 132 | { | 
|  | 133 | if (flash) { | 
|  | 134 | del_mtd_partitions(flash); | 
|  | 135 | map_destroy(flash); | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | if (ocotea_small_map.virt) { | 
|  | 139 | iounmap((void *)ocotea_small_map.virt); | 
|  | 140 | ocotea_small_map.virt = 0; | 
|  | 141 | } | 
|  | 142 |  | 
|  | 143 | if (ocotea_large_map.virt) { | 
|  | 144 | iounmap((void *)ocotea_large_map.virt); | 
|  | 145 | ocotea_large_map.virt = 0; | 
|  | 146 | } | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | module_init(init_ocotea); | 
|  | 150 | module_exit(cleanup_ocotea); | 
|  | 151 |  | 
|  | 152 | MODULE_LICENSE("GPL"); | 
|  | 153 | MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>"); | 
|  | 154 | MODULE_DESCRIPTION("MTD map and partitions for IBM 440GX Ocotea boards"); |