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.
44 #include "physmap-bt1-rom.h"
45 #include "physmap-gemini.h"
46 #include "physmap-ixp4xx.h"
47 #include "physmap-versatile.h"
60 struct gpio_descs *gpios; member
73 if (info->cmtd) { in physmap_flash_remove()
74 WARN_ON(mtd_device_unregister(info->cmtd)); in physmap_flash_remove()
76 if (info->cmtd != info->mtds[0]) in physmap_flash_remove()
77 mtd_concat_destroy(info->cmtd); in physmap_flash_remove()
80 for (i = 0; i < info->nmaps; i++) { in physmap_flash_remove()
81 if (info->mtds[i]) in physmap_flash_remove()
82 map_destroy(info->mtds[i]); in physmap_flash_remove()
85 physmap_data = dev_get_platdata(&dev->dev); in physmap_flash_remove()
86 if (physmap_data && physmap_data->exit) in physmap_flash_remove()
87 physmap_data->exit(dev); in physmap_flash_remove()
89 pm_runtime_put(&dev->dev); in physmap_flash_remove()
90 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()
302 match = of_match_device(of_flash_match, &dev->dev); in of_select_probe_type()
306 probe_type = match->data; in of_select_probe_type()
310 dev_warn(&dev->dev, in of_select_probe_type()
311 "Device tree uses obsolete \"direct-mapped\" flash binding\n"); in of_select_probe_type()
313 of_property_read_string(dp, "probe-type", &probe_type); in of_select_probe_type()
324 dev_warn(&dev->dev, in of_select_probe_type()
336 struct device_node *dp = dev->dev.of_node; in physmap_flash_of_init()
344 return -EINVAL; in physmap_flash_of_init()
346 info->probe_type = of_select_probe_type(dev); in physmap_flash_of_init()
348 info->part_types = of_get_part_probes(dev); in physmap_flash_of_init()
349 if (!info->part_types) in physmap_flash_of_init()
350 return -ENOMEM; in physmap_flash_of_init()
352 of_property_read_string(dp, "linux,mtd-name", &mtd_name); in physmap_flash_of_init()
354 map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access"); in physmap_flash_of_init()
356 err = of_property_read_u32(dp, "bank-width", &bankwidth); in physmap_flash_of_init()
358 dev_err(&dev->dev, "Can't get bank width from device tree\n"); in physmap_flash_of_init()
362 if (of_property_read_bool(dp, "big-endian")) in physmap_flash_of_init()
364 else if (of_property_read_bool(dp, "little-endian")) in physmap_flash_of_init()
367 for (i = 0; i < info->nmaps; i++) { in physmap_flash_of_init()
368 info->maps[i].name = mtd_name; in physmap_flash_of_init()
369 info->maps[i].swap = swap; in physmap_flash_of_init()
370 info->maps[i].bankwidth = bankwidth; in physmap_flash_of_init()
371 info->maps[i].device_node = dp; in physmap_flash_of_init()
373 err = of_flash_probe_bt1_rom(dev, dp, &info->maps[i]); in physmap_flash_of_init()
377 err = of_flash_probe_gemini(dev, dp, &info->maps[i]); in physmap_flash_of_init()
381 err = of_flash_probe_ixp4xx(dev, dp, &info->maps[i]); in physmap_flash_of_init()
385 err = of_flash_probe_versatile(dev, dp, &info->maps[i]); in physmap_flash_of_init()
398 info->maps[i].phys = NO_XIP; in physmap_flash_of_init()
408 return -ENOTSUPP; in physmap_flash_of_init()
427 physmap_data = dev_get_platdata(&dev->dev); in physmap_flash_pdata_init()
429 return -EINVAL; in physmap_flash_pdata_init()
431 info->probe_type = physmap_data->probe_type; in physmap_flash_pdata_init()
432 info->part_types = physmap_data->part_probe_types ? : part_probe_types; in physmap_flash_pdata_init()
433 info->parts = physmap_data->parts; in physmap_flash_pdata_init()
434 info->nparts = physmap_data->nr_parts; in physmap_flash_pdata_init()
436 if (physmap_data->init) { in physmap_flash_pdata_init()
437 err = physmap_data->init(dev); in physmap_flash_pdata_init()
442 for (i = 0; i < info->nmaps; i++) { in physmap_flash_pdata_init()
443 info->maps[i].bankwidth = physmap_data->width; in physmap_flash_pdata_init()
444 info->maps[i].pfow_base = physmap_data->pfow_base; in physmap_flash_pdata_init()
445 info->maps[i].set_vpp = physmap_set_vpp; in physmap_flash_pdata_init()
457 if (!dev->dev.of_node && !dev_get_platdata(&dev->dev)) in physmap_flash_probe()
458 return -EINVAL; in physmap_flash_probe()
460 info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL); in physmap_flash_probe()
462 return -ENOMEM; in physmap_flash_probe()
464 while (platform_get_resource(dev, IORESOURCE_MEM, info->nmaps)) in physmap_flash_probe()
465 info->nmaps++; in physmap_flash_probe()
467 if (!info->nmaps) in physmap_flash_probe()
468 return -ENODEV; in physmap_flash_probe()
470 info->maps = devm_kzalloc(&dev->dev, in physmap_flash_probe()
471 sizeof(*info->maps) * info->nmaps, in physmap_flash_probe()
473 if (!info->maps) in physmap_flash_probe()
474 return -ENOMEM; in physmap_flash_probe()
476 info->mtds = devm_kzalloc(&dev->dev, in physmap_flash_probe()
477 sizeof(*info->mtds) * info->nmaps, in physmap_flash_probe()
479 if (!info->mtds) in physmap_flash_probe()
480 return -ENOMEM; in physmap_flash_probe()
484 info->gpios = devm_gpiod_get_array_optional(&dev->dev, "addr", in physmap_flash_probe()
486 if (IS_ERR(info->gpios)) in physmap_flash_probe()
487 return PTR_ERR(info->gpios); in physmap_flash_probe()
489 if (info->gpios && info->nmaps > 1) { in physmap_flash_probe()
490 dev_err(&dev->dev, "addr-gpios only supported for nmaps == 1\n"); in physmap_flash_probe()
491 return -EINVAL; in physmap_flash_probe()
494 pm_runtime_enable(&dev->dev); in physmap_flash_probe()
495 pm_runtime_get_sync(&dev->dev); in physmap_flash_probe()
497 if (dev->dev.of_node) in physmap_flash_probe()
503 pm_runtime_put(&dev->dev); in physmap_flash_probe()
504 pm_runtime_disable(&dev->dev); in physmap_flash_probe()
508 for (i = 0; i < info->nmaps; i++) { in physmap_flash_probe()
511 info->maps[i].virt = devm_platform_get_and_ioremap_resource(dev, i, &res); in physmap_flash_probe()
512 if (IS_ERR(info->maps[i].virt)) { in physmap_flash_probe()
513 err = PTR_ERR(info->maps[i].virt); in physmap_flash_probe()
517 dev_notice(&dev->dev, "physmap platform flash device: %pR\n", in physmap_flash_probe()
520 if (!info->maps[i].name) in physmap_flash_probe()
521 info->maps[i].name = dev_name(&dev->dev); in physmap_flash_probe()
523 if (!info->maps[i].phys) in physmap_flash_probe()
524 info->maps[i].phys = res->start; in physmap_flash_probe()
526 info->win_order = fls64(resource_size(res)) - 1; in physmap_flash_probe()
527 info->maps[i].size = BIT(info->win_order + in physmap_flash_probe()
528 (info->gpios ? in physmap_flash_probe()
529 info->gpios->ndescs : 0)); in physmap_flash_probe()
531 info->maps[i].map_priv_1 = (unsigned long)dev; in physmap_flash_probe()
533 if (info->gpios) { in physmap_flash_probe()
534 err = physmap_addr_gpios_map_init(&info->maps[i]); in physmap_flash_probe()
542 * implemented. Since map->read() is mandatory checking for its in physmap_flash_probe()
545 if (!info->maps[i].read) in physmap_flash_probe()
546 simple_map_init(&info->maps[i]); in physmap_flash_probe()
548 simple_map_init(&info->maps[i]); in physmap_flash_probe()
551 if (info->probe_type) { in physmap_flash_probe()
552 info->mtds[i] = do_map_probe(info->probe_type, in physmap_flash_probe()
553 &info->maps[i]); in physmap_flash_probe()
556 if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && in physmap_flash_probe()
557 strcmp(info->probe_type, "map_rom")) { in physmap_flash_probe()
558 dev_warn(&dev->dev, in physmap_flash_probe()
560 info->probe_type); in physmap_flash_probe()
562 info->mtds[i] = do_map_probe("map_rom", in physmap_flash_probe()
563 &info->maps[i]); in physmap_flash_probe()
569 info->mtds[i] = do_map_probe(rom_probe_types[j], in physmap_flash_probe()
570 &info->maps[i]); in physmap_flash_probe()
571 if (info->mtds[i]) in physmap_flash_probe()
576 if (!info->mtds[i]) { in physmap_flash_probe()
577 dev_err(&dev->dev, "map_probe failed\n"); in physmap_flash_probe()
578 err = -ENXIO; in physmap_flash_probe()
581 info->mtds[i]->dev.parent = &dev->dev; in physmap_flash_probe()
584 if (info->nmaps == 1) { in physmap_flash_probe()
585 info->cmtd = info->mtds[0]; in physmap_flash_probe()
590 info->cmtd = mtd_concat_create(info->mtds, info->nmaps, in physmap_flash_probe()
591 dev_name(&dev->dev)); in physmap_flash_probe()
592 if (!info->cmtd) in physmap_flash_probe()
593 err = -ENXIO; in physmap_flash_probe()
598 spin_lock_init(&info->vpp_lock); in physmap_flash_probe()
600 mtd_set_of_node(info->cmtd, dev->dev.of_node); in physmap_flash_probe()
601 err = mtd_device_parse_register(info->cmtd, info->part_types, NULL, in physmap_flash_probe()
602 info->parts, info->nparts); in physmap_flash_probe()
619 for (i = 0; i < info->nmaps && info->mtds[i]; i++) in physmap_flash_shutdown()
620 if (mtd_suspend(info->mtds[i]) == 0) in physmap_flash_shutdown()
621 mtd_resume(info->mtds[i]); in physmap_flash_shutdown()
632 .name = "physmap-flash",
644 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
649 .name = "physmap-flash",
695 MODULE_ALIAS("platform:physmap-flash");