Lines Matching +full:bypass +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0+
8 * 031022 - [jsun] add run-time configure and partition setup
19 * line and supplemented by GPIOs. This way you can hook up say a 8MiB flash
20 * to a 2MiB memory range and use the GPIOs to select a particular range.
23 * Copyright © 2005-2009 Analog Devices Inc.
45 #include "physmap-bt1-rom.h"
46 #include "physmap-gemini.h"
47 #include "physmap-ixp4xx.h"
48 #include "physmap-versatile.h"
61 struct gpio_descs *gpios; member
74 if (info->cmtd) { in physmap_flash_remove()
75 WARN_ON(mtd_device_unregister(info->cmtd)); in physmap_flash_remove()
77 if (info->cmtd != info->mtds[0]) in physmap_flash_remove()
78 mtd_concat_destroy(info->cmtd); in physmap_flash_remove()
81 for (i = 0; i < info->nmaps; i++) { in physmap_flash_remove()
82 if (info->mtds[i]) in physmap_flash_remove()
83 map_destroy(info->mtds[i]); in physmap_flash_remove()
86 physmap_data = dev_get_platdata(&dev->dev); in physmap_flash_remove()
87 if (physmap_data && physmap_data->exit) in physmap_flash_remove()
88 physmap_data->exit(dev); in physmap_flash_remove()
90 pm_runtime_put(&dev->dev); in physmap_flash_remove()
91 pm_runtime_disable(&dev->dev); in physmap_flash_remove()
101 pdev = (struct platform_device *)map->map_priv_1; in physmap_set_vpp()
102 physmap_data = dev_get_platdata(&pdev->dev); in physmap_set_vpp()
104 if (!physmap_data->set_vpp) in physmap_set_vpp()
109 spin_lock_irqsave(&info->vpp_lock, flags); in physmap_set_vpp()
111 if (++info->vpp_refcnt == 1) /* first nested 'on' */ in physmap_set_vpp()
112 physmap_data->set_vpp(pdev, 1); in physmap_set_vpp()
114 if (--info->vpp_refcnt == 0) /* last nested 'off' */ in physmap_set_vpp()
115 physmap_data->set_vpp(pdev, 0); in physmap_set_vpp()
117 spin_unlock_irqrestore(&info->vpp_lock, flags); in physmap_set_vpp()
126 ofs >>= info->win_order; in physmap_set_addr_gpios()
127 if (info->gpio_values == ofs) in physmap_set_addr_gpios()
130 for (i = 0; i < info->gpios->ndescs; i++) { in physmap_set_addr_gpios()
131 if ((BIT(i) & ofs) == (BIT(i) & info->gpio_values)) in physmap_set_addr_gpios()
134 gpiod_set_value(info->gpios->desc[i], !!(BIT(i) & ofs)); in physmap_set_addr_gpios()
137 info->gpio_values = ofs; in physmap_set_addr_gpios()
140 #define win_mask(order) (BIT(order) - 1)
150 pdev = (struct platform_device *)map->map_priv_1; in physmap_addr_gpios_read()
154 word = readw(map->virt + (ofs & win_mask(info->win_order))); in physmap_addr_gpios_read()
165 pdev = (struct platform_device *)map->map_priv_1; in physmap_addr_gpios_copy_from()
169 unsigned int winofs = ofs & win_mask(info->win_order); in physmap_addr_gpios_copy_from()
171 BIT(info->win_order) - winofs); in physmap_addr_gpios_copy_from()
174 memcpy_fromio(buf, map->virt + winofs, chunklen); in physmap_addr_gpios_copy_from()
175 len -= chunklen; in physmap_addr_gpios_copy_from()
188 pdev = (struct platform_device *)map->map_priv_1; in physmap_addr_gpios_write()
193 writew(word, map->virt + (ofs & win_mask(info->win_order))); in physmap_addr_gpios_write()
202 pdev = (struct platform_device *)map->map_priv_1; in physmap_addr_gpios_copy_to()
206 unsigned int winofs = ofs & win_mask(info->win_order); in physmap_addr_gpios_copy_to()
208 BIT(info->win_order) - winofs); in physmap_addr_gpios_copy_to()
211 memcpy_toio(map->virt + winofs, buf, chunklen); in physmap_addr_gpios_copy_to()
212 len -= chunklen; in physmap_addr_gpios_copy_to()
220 map->phys = NO_XIP; in physmap_addr_gpios_map_init()
221 map->read = physmap_addr_gpios_read; in physmap_addr_gpios_map_init()
222 map->copy_from = physmap_addr_gpios_copy_from; in physmap_addr_gpios_map_init()
223 map->write = physmap_addr_gpios_write; in physmap_addr_gpios_map_init()
224 map->copy_to = physmap_addr_gpios_copy_to; in physmap_addr_gpios_map_init()
231 return -ENOTSUPP; in physmap_addr_gpios_map_init()
238 .compatible = "cfi-flash",
247 * bypass the heuristic probe code, but the mtd layer
251 .compatible = "jedec-flash",
255 .compatible = "mtd-ram",
259 .compatible = "mtd-rom",
264 .compatible = "direct-mapped"
276 struct device_node *dp = dev->dev.of_node; in of_get_part_probes()
280 count = of_property_count_strings(dp, "linux,part-probe"); in of_get_part_probes()
284 res = devm_kcalloc(&dev->dev, count + 1, sizeof(*res), GFP_KERNEL); in of_get_part_probes()
288 count = of_property_read_string_array(dp, "linux,part-probe", res, in of_get_part_probes()
298 struct device_node *dp = dev->dev.of_node; in of_select_probe_type()
301 probe_type = device_get_match_data(&dev->dev); in of_select_probe_type()
305 dev_warn(&dev->dev, in of_select_probe_type()
306 "Device tree uses obsolete \"direct-mapped\" flash binding\n"); in of_select_probe_type()
308 of_property_read_string(dp, "probe-type", &probe_type); in of_select_probe_type()
319 dev_warn(&dev->dev, in of_select_probe_type()
331 struct device_node *dp = dev->dev.of_node; in physmap_flash_of_init()
339 return -EINVAL; in physmap_flash_of_init()
341 info->probe_type = of_select_probe_type(dev); in physmap_flash_of_init()
343 info->part_types = of_get_part_probes(dev); in physmap_flash_of_init()
344 if (!info->part_types) in physmap_flash_of_init()
345 return -ENOMEM; in physmap_flash_of_init()
347 of_property_read_string(dp, "linux,mtd-name", &mtd_name); in physmap_flash_of_init()
349 map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access"); in physmap_flash_of_init()
351 err = of_property_read_u32(dp, "bank-width", &bankwidth); in physmap_flash_of_init()
353 dev_err(&dev->dev, "Can't get bank width from device tree\n"); in physmap_flash_of_init()
357 if (of_property_read_bool(dp, "big-endian")) in physmap_flash_of_init()
359 else if (of_property_read_bool(dp, "little-endian")) in physmap_flash_of_init()
362 for (i = 0; i < info->nmaps; i++) { in physmap_flash_of_init()
363 info->maps[i].name = mtd_name; in physmap_flash_of_init()
364 info->maps[i].swap = swap; in physmap_flash_of_init()
365 info->maps[i].bankwidth = bankwidth; in physmap_flash_of_init()
366 info->maps[i].device_node = dp; in physmap_flash_of_init()
368 err = of_flash_probe_bt1_rom(dev, dp, &info->maps[i]); in physmap_flash_of_init()
372 err = of_flash_probe_gemini(dev, dp, &info->maps[i]); in physmap_flash_of_init()
376 err = of_flash_probe_ixp4xx(dev, dp, &info->maps[i]); in physmap_flash_of_init()
380 err = of_flash_probe_versatile(dev, dp, &info->maps[i]); in physmap_flash_of_init()
393 info->maps[i].phys = NO_XIP; in physmap_flash_of_init()
403 return -ENOTSUPP; in physmap_flash_of_init()
422 physmap_data = dev_get_platdata(&dev->dev); in physmap_flash_pdata_init()
424 return -EINVAL; in physmap_flash_pdata_init()
426 info->probe_type = physmap_data->probe_type; in physmap_flash_pdata_init()
427 info->part_types = physmap_data->part_probe_types ? : part_probe_types; in physmap_flash_pdata_init()
428 info->parts = physmap_data->parts; in physmap_flash_pdata_init()
429 info->nparts = physmap_data->nr_parts; in physmap_flash_pdata_init()
431 if (physmap_data->init) { in physmap_flash_pdata_init()
432 err = physmap_data->init(dev); in physmap_flash_pdata_init()
437 for (i = 0; i < info->nmaps; i++) { in physmap_flash_pdata_init()
438 info->maps[i].bankwidth = physmap_data->width; in physmap_flash_pdata_init()
439 info->maps[i].pfow_base = physmap_data->pfow_base; in physmap_flash_pdata_init()
440 info->maps[i].set_vpp = physmap_set_vpp; in physmap_flash_pdata_init()
452 if (!dev->dev.of_node && !dev_get_platdata(&dev->dev)) in physmap_flash_probe()
453 return -EINVAL; in physmap_flash_probe()
455 info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL); in physmap_flash_probe()
457 return -ENOMEM; in physmap_flash_probe()
459 while (platform_get_resource(dev, IORESOURCE_MEM, info->nmaps)) in physmap_flash_probe()
460 info->nmaps++; in physmap_flash_probe()
462 if (!info->nmaps) in physmap_flash_probe()
463 return -ENODEV; in physmap_flash_probe()
465 info->maps = devm_kzalloc(&dev->dev, in physmap_flash_probe()
466 sizeof(*info->maps) * info->nmaps, in physmap_flash_probe()
468 if (!info->maps) in physmap_flash_probe()
469 return -ENOMEM; in physmap_flash_probe()
471 info->mtds = devm_kzalloc(&dev->dev, in physmap_flash_probe()
472 sizeof(*info->mtds) * info->nmaps, in physmap_flash_probe()
474 if (!info->mtds) in physmap_flash_probe()
475 return -ENOMEM; in physmap_flash_probe()
479 info->gpios = devm_gpiod_get_array_optional(&dev->dev, "addr", in physmap_flash_probe()
481 if (IS_ERR(info->gpios)) in physmap_flash_probe()
482 return PTR_ERR(info->gpios); in physmap_flash_probe()
484 if (info->gpios && info->nmaps > 1) { in physmap_flash_probe()
485 dev_err(&dev->dev, "addr-gpios only supported for nmaps == 1\n"); in physmap_flash_probe()
486 return -EINVAL; in physmap_flash_probe()
489 pm_runtime_enable(&dev->dev); in physmap_flash_probe()
490 pm_runtime_get_sync(&dev->dev); in physmap_flash_probe()
492 if (dev->dev.of_node) in physmap_flash_probe()
498 pm_runtime_put(&dev->dev); in physmap_flash_probe()
499 pm_runtime_disable(&dev->dev); in physmap_flash_probe()
503 for (i = 0; i < info->nmaps; i++) { in physmap_flash_probe()
506 info->maps[i].virt = devm_platform_get_and_ioremap_resource(dev, i, &res); in physmap_flash_probe()
507 if (IS_ERR(info->maps[i].virt)) { in physmap_flash_probe()
508 err = PTR_ERR(info->maps[i].virt); in physmap_flash_probe()
512 dev_notice(&dev->dev, "physmap platform flash device: %pR\n", in physmap_flash_probe()
515 if (!info->maps[i].name) in physmap_flash_probe()
516 info->maps[i].name = dev_name(&dev->dev); in physmap_flash_probe()
518 if (!info->maps[i].phys) in physmap_flash_probe()
519 info->maps[i].phys = res->start; in physmap_flash_probe()
521 info->win_order = fls64(resource_size(res)) - 1; in physmap_flash_probe()
522 info->maps[i].size = BIT(info->win_order + in physmap_flash_probe()
523 (info->gpios ? in physmap_flash_probe()
524 info->gpios->ndescs : 0)); in physmap_flash_probe()
526 info->maps[i].map_priv_1 = (unsigned long)dev; in physmap_flash_probe()
528 if (info->gpios) { in physmap_flash_probe()
529 err = physmap_addr_gpios_map_init(&info->maps[i]); in physmap_flash_probe()
537 * implemented. Since map->read() is mandatory checking for its in physmap_flash_probe()
540 if (!info->maps[i].read) in physmap_flash_probe()
541 simple_map_init(&info->maps[i]); in physmap_flash_probe()
543 simple_map_init(&info->maps[i]); in physmap_flash_probe()
546 if (info->probe_type) { in physmap_flash_probe()
547 info->mtds[i] = do_map_probe(info->probe_type, in physmap_flash_probe()
548 &info->maps[i]); in physmap_flash_probe()
551 if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && in physmap_flash_probe()
552 strcmp(info->probe_type, "map_rom")) { in physmap_flash_probe()
553 dev_warn(&dev->dev, in physmap_flash_probe()
555 info->probe_type); in physmap_flash_probe()
557 info->mtds[i] = do_map_probe("map_rom", in physmap_flash_probe()
558 &info->maps[i]); in physmap_flash_probe()
564 info->mtds[i] = do_map_probe(rom_probe_types[j], in physmap_flash_probe()
565 &info->maps[i]); in physmap_flash_probe()
566 if (info->mtds[i]) in physmap_flash_probe()
571 if (!info->mtds[i]) { in physmap_flash_probe()
572 dev_err(&dev->dev, "map_probe failed\n"); in physmap_flash_probe()
573 err = -ENXIO; in physmap_flash_probe()
576 info->mtds[i]->dev.parent = &dev->dev; in physmap_flash_probe()
579 if (info->nmaps == 1) { in physmap_flash_probe()
580 info->cmtd = info->mtds[0]; in physmap_flash_probe()
585 info->cmtd = mtd_concat_create(info->mtds, info->nmaps, in physmap_flash_probe()
586 dev_name(&dev->dev)); in physmap_flash_probe()
587 if (!info->cmtd) in physmap_flash_probe()
588 err = -ENXIO; in physmap_flash_probe()
593 spin_lock_init(&info->vpp_lock); in physmap_flash_probe()
595 mtd_set_of_node(info->cmtd, dev->dev.of_node); in physmap_flash_probe()
596 err = mtd_device_parse_register(info->cmtd, info->part_types, NULL, in physmap_flash_probe()
597 info->parts, info->nparts); in physmap_flash_probe()
614 for (i = 0; i < info->nmaps && info->mtds[i]; i++) in physmap_flash_shutdown()
615 if (mtd_suspend(info->mtds[i]) == 0) in physmap_flash_shutdown()
616 mtd_resume(info->mtds[i]); in physmap_flash_shutdown()
627 .name = "physmap-flash",
639 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
644 .name = "physmap-flash",
690 MODULE_ALIAS("platform:physmap-flash");