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