1/* 2 * drivers/mtd/maps/ixp4xx.c 3 * 4 * MTD Map file for IXP4XX based systems. Please do not make per-board 5 * changes in here. If your board needs special setup, do it in your 6 * platform level code in arch/arm/mach-ixp4xx/board-setup.c 7 * 8 * Original Author: Intel Corporation 9 * Maintainer: Deepak Saxena <dsaxena@mvista.com> 10 * 11 * Copyright (C) 2002 Intel Corporation 12 * Copyright (C) 2003-2004 MontaVista Software, Inc. 13 * 14 */ 15 16#include <linux/module.h> 17#include <linux/types.h> 18#include <linux/init.h> 19#include <linux/kernel.h> 20#include <linux/string.h> 21#include <linux/slab.h> 22#include <linux/ioport.h> 23#include <linux/device.h> 24#include <linux/platform_device.h> 25 26#include <linux/mtd/mtd.h> 27#include <linux/mtd/map.h> 28#include <linux/mtd/partitions.h> 29 30#include <asm/io.h> 31#include <asm/mach/flash.h> 32 33#include <linux/reboot.h> 34 35/* 36 * Read/write a 16 bit word from flash address 'addr'. 37 * 38 * When the cpu is in little-endian mode it swizzles the address lines 39 * ('address coherency') so we need to undo the swizzling to ensure commands 40 * and the like end up on the correct flash address. 41 * 42 * To further complicate matters, due to the way the expansion bus controller 43 * handles 32 bit reads, the byte stream ABCD is stored on the flash as: 44 * D15 D0 45 * +---+---+ 46 * | A | B | 0 47 * +---+---+ 48 * | C | D | 2 49 * +---+---+ 50 * This means that on LE systems each 16 bit word must be swapped. Note that 51 * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI 52 * data and other flash commands which are always in D7-D0. 53 */ 54#ifndef __ARMEB__ 55#ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP 56# error CONFIG_MTD_CFI_BE_BYTE_SWAP required 57#endif 58 59static inline u16 flash_read16(void __iomem *addr) 60{ 61 return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2))); 62} 63 64static inline void flash_write16(u16 d, void __iomem *addr) 65{ 66 __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2)); 67} 68 69#define BYTE0(h) ((h) & 0xFF) 70#define BYTE1(h) (((h) >> 8) & 0xFF) 71 72#else 73 74static inline u16 flash_read16(const void __iomem *addr) 75{ 76 return __raw_readw(addr); 77} 78 79static inline void flash_write16(u16 d, void __iomem *addr) 80{ 81 __raw_writew(d, addr); 82} 83 84#define BYTE0(h) (((h) >> 8) & 0xFF) 85#define BYTE1(h) ((h) & 0xFF) 86#endif 87 88static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) 89{ 90 map_word val; 91 val.x[0] = flash_read16(map->virt + ofs); 92 return val; 93} 94 95/* 96 * The IXP4xx expansion bus only allows 16-bit wide acceses 97 * when attached to a 16-bit wide device (such as the 28F128J3A), 98 * so we can't just memcpy_fromio(). 99 */ 100static void ixp4xx_copy_from(struct map_info *map, void *to, 101 unsigned long from, ssize_t len) 102{ 103 u8 *dest = (u8 *) to; 104 void __iomem *src = map->virt + from; 105 106 if (len <= 0) 107 return; 108 109 if (from & 1) { 110 *dest++ = BYTE1(flash_read16(src-1)); 111 src++; 112 --len; 113 } 114 115 while (len >= 2) { 116 u16 data = flash_read16(src); 117 *dest++ = BYTE0(data); 118 *dest++ = BYTE1(data); 119 src += 2; 120 len -= 2; 121 } 122 123 if (len > 0) 124 *dest++ = BYTE0(flash_read16(src)); 125} 126 127/* 128 * Unaligned writes are ignored, causing the 8-bit 129 * probe to fail and proceed to the 16-bit probe (which succeeds). 130 */ 131static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) 132{ 133 if (!(adr & 1)) 134 flash_write16(d.x[0], map->virt + adr); 135} 136 137/* 138 * Fast write16 function without the probing check above 139 */ 140static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) 141{ 142 flash_write16(d.x[0], map->virt + adr); 143} 144 145struct ixp4xx_flash_info { 146 struct mtd_info *mtd; 147 struct map_info map; 148 struct mtd_partition *partitions; 149 struct resource *res; 150}; 151 152static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 153 154static int ixp4xx_flash_remove(struct platform_device *dev) 155{ 156 struct flash_platform_data *plat = dev->dev.platform_data; 157 struct ixp4xx_flash_info *info = platform_get_drvdata(dev); 158 159 platform_set_drvdata(dev, NULL); 160 161 if(!info) 162 return 0; 163 164 if (info->mtd) { 165 del_mtd_partitions(info->mtd); 166 map_destroy(info->mtd); 167 } 168 if (info->map.virt) 169 iounmap(info->map.virt); 170 171 kfree(info->partitions); 172 173 if (info->res) { 174 release_resource(info->res); 175 kfree(info->res); 176 } 177 178 if (plat->exit) 179 plat->exit(); 180 181 return 0; 182} 183 184static int ixp4xx_flash_probe(struct platform_device *dev) 185{ 186 struct flash_platform_data *plat = dev->dev.platform_data; 187 struct ixp4xx_flash_info *info; 188 const char *part_type = NULL; 189 int nr_parts = 0; 190 int err = -1; 191 192 if (!plat) 193 return -ENODEV; 194 195 if (plat->init) { 196 err = plat->init(); 197 if (err) 198 return err; 199 } 200 201 info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL); 202 if(!info) { 203 err = -ENOMEM; 204 goto Error; 205 } 206 207 platform_set_drvdata(dev, info); 208 209 /* 210 * Tell the MTD layer we're not 1:1 mapped so that it does 211 * not attempt to do a direct access on us. 212 */ 213 info->map.phys = NO_XIP; 214 info->map.size = resource_size(dev->resource); 215 216 /* 217 * We only support 16-bit accesses for now. If and when 218 * any board use 8-bit access, we'll fixup the driver to 219 * handle that. 220 */ 221 info->map.bankwidth = 2; 222 info->map.name = dev_name(&dev->dev); 223 info->map.read = ixp4xx_read16; 224 info->map.write = ixp4xx_probe_write16; 225 info->map.copy_from = ixp4xx_copy_from; 226 227 info->res = request_mem_region(dev->resource->start, 228 resource_size(dev->resource), 229 "IXP4XXFlash"); 230 if (!info->res) { 231 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); 232 err = -ENOMEM; 233 goto Error; 234 } 235 236 info->map.virt = ioremap(dev->resource->start, 237 resource_size(dev->resource)); 238 if (!info->map.virt) { 239 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); 240 err = -EIO; 241 goto Error; 242 } 243 244 info->mtd = do_map_probe(plat->map_name, &info->map); 245 if (!info->mtd) { 246 printk(KERN_ERR "IXP4XXFlash: map_probe failed\n"); 247 err = -ENXIO; 248 goto Error; 249 } 250 info->mtd->owner = THIS_MODULE; 251 252 /* Use the fast version */ 253 info->map.write = ixp4xx_write16; 254 255#ifdef CONFIG_MTD_PARTITIONS 256 nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions, 257 dev->resource->start); 258#endif 259 if (nr_parts > 0) { 260 part_type = "dynamic"; 261 } else { 262 info->partitions = plat->parts; 263 nr_parts = plat->nr_parts; 264 part_type = "static"; 265 } 266 if (nr_parts == 0) { 267 printk(KERN_NOTICE "IXP4xx flash: no partition info " 268 "available, registering whole flash\n"); 269 err = add_mtd_device(info->mtd); 270 } else { 271 printk(KERN_NOTICE "IXP4xx flash: using %s partition " 272 "definition\n", part_type); 273 err = add_mtd_partitions(info->mtd, info->partitions, nr_parts); 274 275 if(err) 276 printk(KERN_ERR "Could not parse partitions\n"); 277 } 278 279 if (err) 280 goto Error; 281 282 return 0; 283 284Error: 285 ixp4xx_flash_remove(dev); 286 return err; 287} 288 289static struct platform_driver ixp4xx_flash_driver = { 290 .probe = ixp4xx_flash_probe, 291 .remove = ixp4xx_flash_remove, 292 .driver = { 293 .name = "IXP4XX-Flash", 294 .owner = THIS_MODULE, 295 }, 296}; 297 298static int __init ixp4xx_flash_init(void) 299{ 300 return platform_driver_register(&ixp4xx_flash_driver); 301} 302 303static void __exit ixp4xx_flash_exit(void) 304{ 305 platform_driver_unregister(&ixp4xx_flash_driver); 306} 307 308 309module_init(ixp4xx_flash_init); 310module_exit(ixp4xx_flash_exit); 311 312MODULE_LICENSE("GPL"); 313MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); 314MODULE_AUTHOR("Deepak Saxena"); 315MODULE_ALIAS("platform:IXP4XX-Flash"); 316