Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: maps: Merge physmap_of.c into physmap-core.c

There's no real reason to have two separate driver for the DT and pdata
case. Just do what we do everywhere else and handle DT and pdata
parsing in the same driver.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>

+242 -402
+2 -2
drivers/mtd/maps/Kconfig
··· 66 66 used internally by the CFI drivers. 67 67 68 68 config MTD_PHYSMAP_OF 69 - tristate "Memory device in physical memory map based on OF description" 70 - depends on OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM || MTD_RAM) 69 + bool "Memory device in physical memory map based on OF description" 70 + depends on OF && MTD_PHYSMAP 71 71 help 72 72 This provides a 'mapping' driver which allows the NOR Flash, ROM 73 73 and RAM driver code to communicate with chips which are mapped
+2 -5
drivers/mtd/maps/Makefile
··· 18 18 obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o 19 19 obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o 20 20 physmap-objs-y += physmap-core.o 21 + physmap-objs-$(CONFIG_MTD_PHYSMAP_OF_VERSATILE) += physmap_of_versatile.o 22 + physmap-objs-$(CONFIG_MTD_PHYSMAP_OF_GEMINI) += physmap_of_gemini.o 21 23 physmap-objs := $(physmap-objs-y) 22 24 obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 23 - physmap_of-objs-y += physmap_of_core.o 24 - physmap_of-objs-$(CONFIG_MTD_PHYSMAP_OF_VERSATILE) += physmap_of_versatile.o 25 - physmap_of-objs-$(CONFIG_MTD_PHYSMAP_OF_GEMINI) += physmap_of_gemini.o 26 - physmap_of-objs := $(physmap_of-objs-y) 27 - obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o 28 25 obj-$(CONFIG_MTD_PISMO) += pismo.o 29 26 obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o 30 27 obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
+238 -27
drivers/mtd/maps/physmap-core.c
··· 6 6 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 7 7 * 8 8 * 031022 - [jsun] add run-time configure and partition setup 9 + * 10 + * Device tree support: 11 + * Copyright (C) 2006 MontaVista Software Inc. 12 + * Author: Vitaly Wool <vwool@ru.mvista.com> 13 + * 14 + * Revised to handle newer style flash binding by: 15 + * Copyright (C) 2007 David Gibson, IBM Corporation. 9 16 */ 10 17 11 18 #include <linux/module.h> ··· 27 20 #include <linux/mtd/partitions.h> 28 21 #include <linux/mtd/physmap.h> 29 22 #include <linux/mtd/concat.h> 23 + #include <linux/mtd/cfi_endian.h> 30 24 #include <linux/io.h> 25 + #include <linux/of_device.h> 26 + 27 + #include "physmap_of_gemini.h" 28 + #include "physmap_of_versatile.h" 31 29 32 30 struct physmap_flash_info { 33 31 unsigned int nmaps; ··· 41 29 struct map_info *maps; 42 30 spinlock_t vpp_lock; 43 31 int vpp_refcnt; 32 + const char *probe_type; 33 + const char * const *part_types; 34 + unsigned int nparts; 35 + const struct mtd_partition *parts; 44 36 }; 45 37 46 38 static int physmap_flash_remove(struct platform_device *dev) ··· 56 40 info = platform_get_drvdata(dev); 57 41 if (!info) 58 42 return 0; 59 - 60 - physmap_data = dev_get_platdata(&dev->dev); 61 43 62 44 if (info->cmtd) { 63 45 err = mtd_device_unregister(info->cmtd); ··· 71 57 map_destroy(info->mtds[i]); 72 58 } 73 59 74 - if (physmap_data->exit) 60 + physmap_data = dev_get_platdata(&dev->dev); 61 + if (physmap_data && physmap_data->exit) 75 62 physmap_data->exit(dev); 76 63 77 64 return 0; ··· 104 89 spin_unlock_irqrestore(&info->vpp_lock, flags); 105 90 } 106 91 92 + #if IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) 93 + static const struct of_device_id of_flash_match[] = { 94 + { 95 + .compatible = "cfi-flash", 96 + .data = "cfi_probe", 97 + }, 98 + { 99 + /* 100 + * FIXME: JEDEC chips can't be safely and reliably 101 + * probed, although the mtd code gets it right in 102 + * practice most of the time. We should use the 103 + * vendor and device ids specified by the binding to 104 + * bypass the heuristic probe code, but the mtd layer 105 + * provides, at present, no interface for doing so 106 + * :(. 107 + */ 108 + .compatible = "jedec-flash", 109 + .data = "jedec_probe", 110 + }, 111 + { 112 + .compatible = "mtd-ram", 113 + .data = "map_ram", 114 + }, 115 + { 116 + .compatible = "mtd-rom", 117 + .data = "map_rom", 118 + }, 119 + { 120 + .type = "rom", 121 + .compatible = "direct-mapped" 122 + }, 123 + { /* sentinel */ }, 124 + }; 125 + MODULE_DEVICE_TABLE(of, of_flash_match); 126 + 127 + static const char * const of_default_part_probes[] = { 128 + "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL 129 + }; 130 + 131 + static const char * const *of_get_part_probes(struct platform_device *dev) 132 + { 133 + struct device_node *dp = dev->dev.of_node; 134 + const char **res; 135 + int count; 136 + 137 + count = of_property_count_strings(dp, "linux,part-probe"); 138 + if (count < 0) 139 + return of_default_part_probes; 140 + 141 + res = devm_kcalloc(&dev->dev, count + 1, sizeof(*res), GFP_KERNEL); 142 + if (!res) 143 + return NULL; 144 + 145 + count = of_property_read_string_array(dp, "linux,part-probe", res, 146 + count); 147 + if (count < 0) 148 + return NULL; 149 + 150 + return res; 151 + } 152 + 153 + static const char *of_select_probe_type(struct platform_device *dev) 154 + { 155 + struct device_node *dp = dev->dev.of_node; 156 + const struct of_device_id *match; 157 + const char *probe_type; 158 + 159 + match = of_match_device(of_flash_match, &dev->dev); 160 + probe_type = match->data; 161 + if (probe_type) 162 + return probe_type; 163 + 164 + dev_warn(&dev->dev, 165 + "Device tree uses obsolete \"direct-mapped\" flash binding\n"); 166 + 167 + of_property_read_string(dp, "probe-type", &probe_type); 168 + if (!probe_type) 169 + return NULL; 170 + 171 + if (!strcmp(probe_type, "CFI")) { 172 + probe_type = "cfi_probe"; 173 + } else if (!strcmp(probe_type, "JEDEC")) { 174 + probe_type = "jedec_probe"; 175 + } else if (!strcmp(probe_type, "ROM")) { 176 + probe_type = "map_rom"; 177 + } else { 178 + dev_warn(&dev->dev, 179 + "obsolete_probe: don't know probe type '%s', mapping as rom\n", 180 + probe_type); 181 + probe_type = "map_rom"; 182 + } 183 + 184 + return probe_type; 185 + } 186 + 187 + static int physmap_flash_of_init(struct platform_device *dev) 188 + { 189 + struct physmap_flash_info *info = platform_get_drvdata(dev); 190 + struct device_node *dp = dev->dev.of_node; 191 + const char *mtd_name = NULL; 192 + int err, swap = 0; 193 + bool map_indirect; 194 + unsigned int i; 195 + u32 bankwidth; 196 + 197 + if (!dp) 198 + return -EINVAL; 199 + 200 + info->probe_type = of_select_probe_type(dev); 201 + 202 + info->part_types = of_get_part_probes(dev); 203 + if (!info->part_types) 204 + return -ENOMEM; 205 + 206 + of_property_read_string(dp, "linux,mtd-name", &mtd_name); 207 + 208 + map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access"); 209 + 210 + err = of_property_read_u32(dp, "bank-width", &bankwidth); 211 + if (err) { 212 + dev_err(&dev->dev, "Can't get bank width from device tree\n"); 213 + return err; 214 + } 215 + 216 + if (of_property_read_bool(dp, "big-endian")) 217 + swap = CFI_BIG_ENDIAN; 218 + else if (of_property_read_bool(dp, "little-endian")) 219 + swap = CFI_LITTLE_ENDIAN; 220 + 221 + for (i = 0; i < info->nmaps; i++) { 222 + info->maps[i].name = mtd_name; 223 + info->maps[i].swap = swap; 224 + info->maps[i].bankwidth = bankwidth; 225 + info->maps[i].device_node = dp; 226 + 227 + err = of_flash_probe_gemini(dev, dp, &info->maps[i]); 228 + if (err) 229 + return err; 230 + 231 + err = of_flash_probe_versatile(dev, dp, &info->maps[i]); 232 + if (err) 233 + return err; 234 + 235 + /* 236 + * On some platforms (e.g. MPC5200) a direct 1:1 mapping 237 + * may cause problems with JFFS2 usage, as the local bus (LPB) 238 + * doesn't support unaligned accesses as implemented in the 239 + * JFFS2 code via memcpy(). By setting NO_XIP, the 240 + * flash will not be exposed directly to the MTD users 241 + * (e.g. JFFS2) any more. 242 + */ 243 + if (map_indirect) 244 + info->maps[i].phys = NO_XIP; 245 + } 246 + 247 + return 0; 248 + } 249 + #else /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */ 250 + #define of_flash_match NULL 251 + 252 + static int physmap_flash_of_init(struct platform_device *dev) 253 + { 254 + return -ENOTSUPP; 255 + } 256 + #endif /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */ 257 + 107 258 static const char * const rom_probe_types[] = { 108 259 "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom", NULL 109 260 }; ··· 278 97 "cmdlinepart", "RedBoot", "afs", NULL 279 98 }; 280 99 281 - static int physmap_flash_probe(struct platform_device *dev) 100 + static int physmap_flash_pdata_init(struct platform_device *dev) 282 101 { 102 + struct physmap_flash_info *info = platform_get_drvdata(dev); 283 103 struct physmap_flash_data *physmap_data; 284 - struct physmap_flash_info *info; 285 - const char * const *probe_type; 286 - const char * const *part_types; 287 - int err = 0; 288 - int i; 104 + unsigned int i; 105 + int err; 289 106 290 107 physmap_data = dev_get_platdata(&dev->dev); 291 108 if (!physmap_data) 292 - return -ENODEV; 109 + return -EINVAL; 110 + 111 + info->probe_type = physmap_data->probe_type; 112 + info->part_types = physmap_data->part_probe_types ? : part_probe_types; 113 + info->parts = physmap_data->parts; 114 + info->nparts = physmap_data->nr_parts; 115 + 116 + if (physmap_data->init) { 117 + err = physmap_data->init(dev); 118 + if (err) 119 + return err; 120 + } 121 + 122 + for (i = 0; i < info->nmaps; i++) { 123 + info->maps[i].bankwidth = physmap_data->width; 124 + info->maps[i].pfow_base = physmap_data->pfow_base; 125 + info->maps[i].set_vpp = physmap_set_vpp; 126 + } 127 + 128 + return 0; 129 + } 130 + 131 + static int physmap_flash_probe(struct platform_device *dev) 132 + { 133 + struct physmap_flash_info *info; 134 + const char * const *probe_type; 135 + int err = 0; 136 + int i; 137 + 138 + if (!dev->dev.of_node && !dev_get_platdata(&dev->dev)) 139 + return -EINVAL; 293 140 294 141 info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL); 295 142 if (!info) ··· 341 132 if (!info->mtds) 342 133 return -ENOMEM; 343 134 344 - if (physmap_data->init) { 345 - err = physmap_data->init(dev); 346 - if (err) 347 - goto err_out; 348 - } 349 - 350 135 platform_set_drvdata(dev, info); 136 + 137 + if (dev->dev.of_node) 138 + err = physmap_flash_of_init(dev); 139 + else 140 + err = physmap_flash_pdata_init(dev); 141 + 142 + if (err) 143 + return err; 351 144 352 145 for (i = 0; i < info->nmaps; i++) { 353 146 struct resource *res; ··· 365 154 res); 366 155 367 156 info->maps[i].name = dev_name(&dev->dev); 368 - info->maps[i].phys = res->start; 157 + 158 + if (!info->maps[i].phys) 159 + info->maps[i].phys = res->start; 160 + 369 161 info->maps[i].size = resource_size(res); 370 - info->maps[i].bankwidth = physmap_data->width; 371 - info->maps[i].set_vpp = physmap_set_vpp; 372 - info->maps[i].pfow_base = physmap_data->pfow_base; 373 162 info->maps[i].map_priv_1 = (unsigned long)dev; 374 163 375 164 simple_map_init(&info->maps[i]); 376 165 377 166 probe_type = rom_probe_types; 378 - if (!physmap_data->probe_type) { 167 + if (!info->probe_type) { 379 168 for (; !info->mtds[i] && *probe_type; probe_type++) 380 169 info->mtds[i] = do_map_probe(*probe_type, 381 170 &info->maps[i]); 382 171 } else { 383 - info->mtds[i] = do_map_probe(physmap_data->probe_type, 172 + info->mtds[i] = do_map_probe(info->probe_type, 384 173 &info->maps[i]); 385 174 } 386 175 ··· 408 197 409 198 spin_lock_init(&info->vpp_lock); 410 199 411 - part_types = physmap_data->part_probe_types ? : part_probe_types; 412 - 413 - err = mtd_device_parse_register(info->cmtd, part_types, NULL, 414 - physmap_data->parts, 415 - physmap_data->nr_parts); 200 + mtd_set_of_node(info->cmtd, dev->dev.of_node); 201 + err = mtd_device_parse_register(info->cmtd, info->part_types, NULL, 202 + info->parts, info->nparts); 416 203 if (err) 417 204 goto err_out; 418 205 ··· 441 232 .shutdown = physmap_flash_shutdown, 442 233 .driver = { 443 234 .name = "physmap-flash", 235 + .of_match_table = of_flash_match, 444 236 }, 445 237 }; 446 238 ··· 496 286 497 287 MODULE_LICENSE("GPL"); 498 288 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 289 + MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); 499 290 MODULE_DESCRIPTION("Generic configurable MTD map driver"); 500 291 501 292 /* legacy platform drivers can't hotplug or coldplg */
-368
drivers/mtd/maps/physmap_of_core.c
··· 1 - /* 2 - * Flash mappings described by the OF (or flattened) device tree 3 - * 4 - * Copyright (C) 2006 MontaVista Software Inc. 5 - * Author: Vitaly Wool <vwool@ru.mvista.com> 6 - * 7 - * Revised to handle newer style flash binding by: 8 - * Copyright (C) 2007 David Gibson, IBM Corporation. 9 - * 10 - * This program is free software; you can redistribute it and/or modify it 11 - * under the terms of the GNU General Public License as published by the 12 - * Free Software Foundation; either version 2 of the License, or (at your 13 - * option) any later version. 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/types.h> 18 - #include <linux/device.h> 19 - #include <linux/mtd/mtd.h> 20 - #include <linux/mtd/map.h> 21 - #include <linux/mtd/partitions.h> 22 - #include <linux/mtd/concat.h> 23 - #include <linux/mtd/cfi_endian.h> 24 - #include <linux/of.h> 25 - #include <linux/of_address.h> 26 - #include <linux/of_platform.h> 27 - #include <linux/slab.h> 28 - #include "physmap_of_gemini.h" 29 - #include "physmap_of_versatile.h" 30 - 31 - struct of_flash_list { 32 - struct mtd_info *mtd; 33 - struct map_info map; 34 - }; 35 - 36 - struct of_flash { 37 - struct mtd_info *cmtd; 38 - int list_size; /* number of elements in of_flash_list */ 39 - struct of_flash_list list[0]; 40 - }; 41 - 42 - static int of_flash_remove(struct platform_device *dev) 43 - { 44 - struct of_flash *info; 45 - int i; 46 - 47 - info = dev_get_drvdata(&dev->dev); 48 - if (!info) 49 - return 0; 50 - dev_set_drvdata(&dev->dev, NULL); 51 - 52 - if (info->cmtd) { 53 - mtd_device_unregister(info->cmtd); 54 - if (info->cmtd != info->list[0].mtd) 55 - mtd_concat_destroy(info->cmtd); 56 - } 57 - 58 - for (i = 0; i < info->list_size; i++) 59 - if (info->list[i].mtd) 60 - map_destroy(info->list[i].mtd); 61 - 62 - return 0; 63 - } 64 - 65 - static const char * const rom_probe_types[] = { 66 - "cfi_probe", "jedec_probe", "map_rom" }; 67 - 68 - /* Helper function to handle probing of the obsolete "direct-mapped" 69 - * compatible binding, which has an extra "probe-type" property 70 - * describing the type of flash probe necessary. */ 71 - static struct mtd_info *obsolete_probe(struct platform_device *dev, 72 - struct map_info *map) 73 - { 74 - struct device_node *dp = dev->dev.of_node; 75 - const char *of_probe; 76 - struct mtd_info *mtd; 77 - int i; 78 - 79 - dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" " 80 - "flash binding\n"); 81 - 82 - of_probe = of_get_property(dp, "probe-type", NULL); 83 - if (!of_probe) { 84 - for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) { 85 - mtd = do_map_probe(rom_probe_types[i], map); 86 - if (mtd) 87 - return mtd; 88 - } 89 - return NULL; 90 - } else if (strcmp(of_probe, "CFI") == 0) { 91 - return do_map_probe("cfi_probe", map); 92 - } else if (strcmp(of_probe, "JEDEC") == 0) { 93 - return do_map_probe("jedec_probe", map); 94 - } else { 95 - if (strcmp(of_probe, "ROM") != 0) 96 - dev_warn(&dev->dev, "obsolete_probe: don't know probe " 97 - "type '%s', mapping as rom\n", of_probe); 98 - return do_map_probe("map_rom", map); 99 - } 100 - } 101 - 102 - /* When partitions are set we look for a linux,part-probe property which 103 - specifies the list of partition probers to use. If none is given then the 104 - default is use. These take precedence over other device tree 105 - information. */ 106 - static const char * const part_probe_types_def[] = { 107 - "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; 108 - 109 - static const char * const *of_get_probes(struct device_node *dp) 110 - { 111 - const char **res; 112 - int count; 113 - 114 - count = of_property_count_strings(dp, "linux,part-probe"); 115 - if (count < 0) 116 - return part_probe_types_def; 117 - 118 - res = kcalloc(count + 1, sizeof(*res), GFP_KERNEL); 119 - if (!res) 120 - return NULL; 121 - 122 - count = of_property_read_string_array(dp, "linux,part-probe", res, 123 - count); 124 - if (count < 0) 125 - return NULL; 126 - 127 - return res; 128 - } 129 - 130 - static void of_free_probes(const char * const *probes) 131 - { 132 - if (probes != part_probe_types_def) 133 - kfree(probes); 134 - } 135 - 136 - static const struct of_device_id of_flash_match[]; 137 - static int of_flash_probe(struct platform_device *dev) 138 - { 139 - const char * const *part_probe_types; 140 - const struct of_device_id *match; 141 - struct device_node *dp = dev->dev.of_node; 142 - struct resource res; 143 - struct of_flash *info; 144 - const char *probe_type; 145 - const __be32 *width; 146 - int err; 147 - int i; 148 - int count; 149 - const __be32 *p; 150 - int reg_tuple_size; 151 - struct mtd_info **mtd_list = NULL; 152 - resource_size_t res_size; 153 - bool map_indirect; 154 - const char *mtd_name = NULL; 155 - 156 - match = of_match_device(of_flash_match, &dev->dev); 157 - if (!match) 158 - return -EINVAL; 159 - probe_type = match->data; 160 - 161 - reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); 162 - 163 - of_property_read_string(dp, "linux,mtd-name", &mtd_name); 164 - 165 - /* 166 - * Get number of "reg" tuples. Scan for MTD devices on area's 167 - * described by each "reg" region. This makes it possible (including 168 - * the concat support) to support the Intel P30 48F4400 chips which 169 - * consists internally of 2 non-identical NOR chips on one die. 170 - */ 171 - p = of_get_property(dp, "reg", &count); 172 - if (!p || count % reg_tuple_size != 0) { 173 - dev_err(&dev->dev, "Malformed reg property on %pOF\n", 174 - dev->dev.of_node); 175 - err = -EINVAL; 176 - goto err_flash_remove; 177 - } 178 - count /= reg_tuple_size; 179 - 180 - map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access"); 181 - 182 - err = -ENOMEM; 183 - info = devm_kzalloc(&dev->dev, 184 - sizeof(struct of_flash) + 185 - sizeof(struct of_flash_list) * count, GFP_KERNEL); 186 - if (!info) 187 - goto err_flash_remove; 188 - 189 - dev_set_drvdata(&dev->dev, info); 190 - 191 - mtd_list = kcalloc(count, sizeof(*mtd_list), GFP_KERNEL); 192 - if (!mtd_list) 193 - goto err_flash_remove; 194 - 195 - for (i = 0; i < count; i++) { 196 - err = -ENXIO; 197 - if (of_address_to_resource(dp, i, &res)) { 198 - /* 199 - * Continue with next register tuple if this 200 - * one is not mappable 201 - */ 202 - continue; 203 - } 204 - 205 - dev_dbg(&dev->dev, "of_flash device: %pR\n", &res); 206 - 207 - err = -EBUSY; 208 - res_size = resource_size(&res); 209 - info->list[i].map.virt = devm_ioremap_resource(&dev->dev, &res); 210 - if (IS_ERR(info->list[i].map.virt)) { 211 - err = PTR_ERR(info->list[i].map.virt); 212 - goto err_out; 213 - } 214 - 215 - err = -ENXIO; 216 - width = of_get_property(dp, "bank-width", NULL); 217 - if (!width) { 218 - dev_err(&dev->dev, "Can't get bank width from device" 219 - " tree\n"); 220 - goto err_out; 221 - } 222 - 223 - info->list[i].map.name = mtd_name ?: dev_name(&dev->dev); 224 - info->list[i].map.phys = res.start; 225 - info->list[i].map.size = res_size; 226 - info->list[i].map.bankwidth = be32_to_cpup(width); 227 - info->list[i].map.device_node = dp; 228 - 229 - if (of_property_read_bool(dp, "big-endian")) 230 - info->list[i].map.swap = CFI_BIG_ENDIAN; 231 - else if (of_property_read_bool(dp, "little-endian")) 232 - info->list[i].map.swap = CFI_LITTLE_ENDIAN; 233 - 234 - err = of_flash_probe_gemini(dev, dp, &info->list[i].map); 235 - if (err) 236 - goto err_out; 237 - err = of_flash_probe_versatile(dev, dp, &info->list[i].map); 238 - if (err) 239 - goto err_out; 240 - 241 - simple_map_init(&info->list[i].map); 242 - 243 - /* 244 - * On some platforms (e.g. MPC5200) a direct 1:1 mapping 245 - * may cause problems with JFFS2 usage, as the local bus (LPB) 246 - * doesn't support unaligned accesses as implemented in the 247 - * JFFS2 code via memcpy(). By setting NO_XIP, the 248 - * flash will not be exposed directly to the MTD users 249 - * (e.g. JFFS2) any more. 250 - */ 251 - if (map_indirect) 252 - info->list[i].map.phys = NO_XIP; 253 - 254 - if (probe_type) { 255 - info->list[i].mtd = do_map_probe(probe_type, 256 - &info->list[i].map); 257 - } else { 258 - info->list[i].mtd = obsolete_probe(dev, 259 - &info->list[i].map); 260 - } 261 - 262 - /* Fall back to mapping region as ROM */ 263 - if (!info->list[i].mtd) { 264 - dev_warn(&dev->dev, 265 - "do_map_probe() failed for type %s\n", 266 - probe_type); 267 - 268 - info->list[i].mtd = do_map_probe("map_rom", 269 - &info->list[i].map); 270 - } 271 - mtd_list[i] = info->list[i].mtd; 272 - 273 - err = -ENXIO; 274 - if (!info->list[i].mtd) { 275 - dev_err(&dev->dev, "do_map_probe() failed\n"); 276 - goto err_out; 277 - } else { 278 - info->list_size++; 279 - } 280 - info->list[i].mtd->dev.parent = &dev->dev; 281 - } 282 - 283 - err = 0; 284 - info->cmtd = NULL; 285 - if (info->list_size == 1) { 286 - info->cmtd = info->list[0].mtd; 287 - } else if (info->list_size > 1) { 288 - /* 289 - * We detected multiple devices. Concatenate them together. 290 - */ 291 - info->cmtd = mtd_concat_create(mtd_list, info->list_size, 292 - dev_name(&dev->dev)); 293 - } 294 - if (info->cmtd == NULL) 295 - err = -ENXIO; 296 - 297 - if (err) 298 - goto err_out; 299 - 300 - info->cmtd->dev.parent = &dev->dev; 301 - mtd_set_of_node(info->cmtd, dp); 302 - part_probe_types = of_get_probes(dp); 303 - if (!part_probe_types) { 304 - err = -ENOMEM; 305 - goto err_out; 306 - } 307 - mtd_device_parse_register(info->cmtd, part_probe_types, NULL, 308 - NULL, 0); 309 - of_free_probes(part_probe_types); 310 - 311 - kfree(mtd_list); 312 - 313 - return 0; 314 - 315 - err_out: 316 - kfree(mtd_list); 317 - err_flash_remove: 318 - of_flash_remove(dev); 319 - 320 - return err; 321 - } 322 - 323 - static const struct of_device_id of_flash_match[] = { 324 - { 325 - .compatible = "cfi-flash", 326 - .data = (void *)"cfi_probe", 327 - }, 328 - { 329 - /* FIXME: JEDEC chips can't be safely and reliably 330 - * probed, although the mtd code gets it right in 331 - * practice most of the time. We should use the 332 - * vendor and device ids specified by the binding to 333 - * bypass the heuristic probe code, but the mtd layer 334 - * provides, at present, no interface for doing so 335 - * :(. */ 336 - .compatible = "jedec-flash", 337 - .data = (void *)"jedec_probe", 338 - }, 339 - { 340 - .compatible = "mtd-ram", 341 - .data = (void *)"map_ram", 342 - }, 343 - { 344 - .compatible = "mtd-rom", 345 - .data = (void *)"map_rom", 346 - }, 347 - { 348 - .type = "rom", 349 - .compatible = "direct-mapped" 350 - }, 351 - { }, 352 - }; 353 - MODULE_DEVICE_TABLE(of, of_flash_match); 354 - 355 - static struct platform_driver of_flash_driver = { 356 - .driver = { 357 - .name = "of-flash", 358 - .of_match_table = of_flash_match, 359 - }, 360 - .probe = of_flash_probe, 361 - .remove = of_flash_remove, 362 - }; 363 - 364 - module_platform_driver(of_flash_driver); 365 - 366 - MODULE_LICENSE("GPL"); 367 - MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); 368 - MODULE_DESCRIPTION("Device tree based MTD map driver");