1 // SPDX-License-Identifier: GPL-2.0+
3 * Normal mappings of chips in physical memory
5 * Copyright (C) 2003 MontaVista Software Inc.
6 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 * 031022 - [jsun] add run-time configure and partition setup
10 * Device tree support:
11 * Copyright (C) 2006 MontaVista Software Inc.
12 * Author: Vitaly Wool <vwool@ru.mvista.com>
14 * Revised to handle newer style flash binding by:
15 * Copyright (C) 2007 David Gibson, IBM Corporation.
17 * GPIO address extension:
18 * Handle the case where a flash device is mostly addressed using physical
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.
22 * Copyright © 2000 Nicolas Pitre <nico@cam.org>
23 * Copyright © 2005-2009 Analog Devices Inc.
26 #include <linux/module.h>
27 #include <linux/types.h>
28 #include <linux/kernel.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/device.h>
32 #include <linux/platform_device.h>
33 #include <linux/property.h>
34 #include <linux/mtd/mtd.h>
35 #include <linux/mtd/map.h>
36 #include <linux/mtd/partitions.h>
37 #include <linux/mtd/physmap.h>
38 #include <linux/mtd/concat.h>
39 #include <linux/mtd/cfi_endian.h>
42 #include <linux/pm_runtime.h>
43 #include <linux/gpio/consumer.h>
45 #include "physmap-bt1-rom.h"
46 #include "physmap-gemini.h"
47 #include "physmap-ixp4xx.h"
48 #include "physmap-versatile.h"
50 struct physmap_flash_info
{
52 struct mtd_info
**mtds
;
53 struct mtd_info
*cmtd
;
54 struct map_info
*maps
;
57 const char *probe_type
;
58 const char * const *part_types
;
60 const struct mtd_partition
*parts
;
61 struct gpio_descs
*gpios
;
62 unsigned int gpio_values
;
63 unsigned int win_order
;
66 static void physmap_flash_remove(struct platform_device
*dev
)
68 struct physmap_flash_info
*info
;
69 struct physmap_flash_data
*physmap_data
;
72 info
= platform_get_drvdata(dev
);
75 WARN_ON(mtd_device_unregister(info
->cmtd
));
77 if (info
->cmtd
!= info
->mtds
[0])
78 mtd_concat_destroy(info
->cmtd
);
81 for (i
= 0; i
< info
->nmaps
; i
++) {
83 map_destroy(info
->mtds
[i
]);
86 physmap_data
= dev_get_platdata(&dev
->dev
);
87 if (physmap_data
&& physmap_data
->exit
)
88 physmap_data
->exit(dev
);
90 pm_runtime_put(&dev
->dev
);
91 pm_runtime_disable(&dev
->dev
);
94 static void physmap_set_vpp(struct map_info
*map
, int state
)
96 struct platform_device
*pdev
;
97 struct physmap_flash_data
*physmap_data
;
98 struct physmap_flash_info
*info
;
101 pdev
= (struct platform_device
*)map
->map_priv_1
;
102 physmap_data
= dev_get_platdata(&pdev
->dev
);
104 if (!physmap_data
->set_vpp
)
107 info
= platform_get_drvdata(pdev
);
109 spin_lock_irqsave(&info
->vpp_lock
, flags
);
111 if (++info
->vpp_refcnt
== 1) /* first nested 'on' */
112 physmap_data
->set_vpp(pdev
, 1);
114 if (--info
->vpp_refcnt
== 0) /* last nested 'off' */
115 physmap_data
->set_vpp(pdev
, 0);
117 spin_unlock_irqrestore(&info
->vpp_lock
, flags
);
120 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_GPIO_ADDR)
121 static void physmap_set_addr_gpios(struct physmap_flash_info
*info
,
126 ofs
>>= info
->win_order
;
127 if (info
->gpio_values
== ofs
)
130 for (i
= 0; i
< info
->gpios
->ndescs
; i
++) {
131 if ((BIT(i
) & ofs
) == (BIT(i
) & info
->gpio_values
))
134 gpiod_set_value(info
->gpios
->desc
[i
], !!(BIT(i
) & ofs
));
137 info
->gpio_values
= ofs
;
140 #define win_mask(order) (BIT(order) - 1)
142 static map_word
physmap_addr_gpios_read(struct map_info
*map
,
145 struct platform_device
*pdev
;
146 struct physmap_flash_info
*info
;
150 pdev
= (struct platform_device
*)map
->map_priv_1
;
151 info
= platform_get_drvdata(pdev
);
152 physmap_set_addr_gpios(info
, ofs
);
154 word
= readw(map
->virt
+ (ofs
& win_mask(info
->win_order
)));
159 static void physmap_addr_gpios_copy_from(struct map_info
*map
, void *buf
,
160 unsigned long ofs
, ssize_t len
)
162 struct platform_device
*pdev
;
163 struct physmap_flash_info
*info
;
165 pdev
= (struct platform_device
*)map
->map_priv_1
;
166 info
= platform_get_drvdata(pdev
);
169 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
170 unsigned int chunklen
= min_t(unsigned int, len
,
171 BIT(info
->win_order
) - winofs
);
173 physmap_set_addr_gpios(info
, ofs
);
174 memcpy_fromio(buf
, map
->virt
+ winofs
, chunklen
);
181 static void physmap_addr_gpios_write(struct map_info
*map
, map_word mw
,
184 struct platform_device
*pdev
;
185 struct physmap_flash_info
*info
;
188 pdev
= (struct platform_device
*)map
->map_priv_1
;
189 info
= platform_get_drvdata(pdev
);
190 physmap_set_addr_gpios(info
, ofs
);
193 writew(word
, map
->virt
+ (ofs
& win_mask(info
->win_order
)));
196 static void physmap_addr_gpios_copy_to(struct map_info
*map
, unsigned long ofs
,
197 const void *buf
, ssize_t len
)
199 struct platform_device
*pdev
;
200 struct physmap_flash_info
*info
;
202 pdev
= (struct platform_device
*)map
->map_priv_1
;
203 info
= platform_get_drvdata(pdev
);
206 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
207 unsigned int chunklen
= min_t(unsigned int, len
,
208 BIT(info
->win_order
) - winofs
);
210 physmap_set_addr_gpios(info
, ofs
);
211 memcpy_toio(map
->virt
+ winofs
, buf
, chunklen
);
218 static int physmap_addr_gpios_map_init(struct map_info
*map
)
221 map
->read
= physmap_addr_gpios_read
;
222 map
->copy_from
= physmap_addr_gpios_copy_from
;
223 map
->write
= physmap_addr_gpios_write
;
224 map
->copy_to
= physmap_addr_gpios_copy_to
;
229 static int physmap_addr_gpios_map_init(struct map_info
*map
)
235 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_OF)
236 static const struct of_device_id of_flash_match
[] = {
238 .compatible
= "cfi-flash",
243 * FIXME: JEDEC chips can't be safely and reliably
244 * probed, although the mtd code gets it right in
245 * practice most of the time. We should use the
246 * vendor and device ids specified by the binding to
247 * bypass the heuristic probe code, but the mtd layer
248 * provides, at present, no interface for doing so
251 .compatible
= "jedec-flash",
252 .data
= "jedec_probe",
255 .compatible
= "mtd-ram",
259 .compatible
= "mtd-rom",
264 .compatible
= "direct-mapped"
268 MODULE_DEVICE_TABLE(of
, of_flash_match
);
270 static const char * const of_default_part_probes
[] = {
271 "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL
274 static const char * const *of_get_part_probes(struct platform_device
*dev
)
276 struct device_node
*dp
= dev
->dev
.of_node
;
280 count
= of_property_count_strings(dp
, "linux,part-probe");
282 return of_default_part_probes
;
284 res
= devm_kcalloc(&dev
->dev
, count
+ 1, sizeof(*res
), GFP_KERNEL
);
288 count
= of_property_read_string_array(dp
, "linux,part-probe", res
,
296 static const char *of_select_probe_type(struct platform_device
*dev
)
298 struct device_node
*dp
= dev
->dev
.of_node
;
299 const char *probe_type
;
301 probe_type
= device_get_match_data(&dev
->dev
);
306 "Device tree uses obsolete \"direct-mapped\" flash binding\n");
308 of_property_read_string(dp
, "probe-type", &probe_type
);
312 if (!strcmp(probe_type
, "CFI")) {
313 probe_type
= "cfi_probe";
314 } else if (!strcmp(probe_type
, "JEDEC")) {
315 probe_type
= "jedec_probe";
316 } else if (!strcmp(probe_type
, "ROM")) {
317 probe_type
= "map_rom";
320 "obsolete_probe: don't know probe type '%s', mapping as rom\n",
322 probe_type
= "map_rom";
328 static int physmap_flash_of_init(struct platform_device
*dev
)
330 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
331 struct device_node
*dp
= dev
->dev
.of_node
;
332 const char *mtd_name
= NULL
;
341 info
->probe_type
= of_select_probe_type(dev
);
343 info
->part_types
= of_get_part_probes(dev
);
344 if (!info
->part_types
)
347 of_property_read_string(dp
, "linux,mtd-name", &mtd_name
);
349 map_indirect
= of_property_read_bool(dp
, "no-unaligned-direct-access");
351 err
= of_property_read_u32(dp
, "bank-width", &bankwidth
);
353 dev_err(&dev
->dev
, "Can't get bank width from device tree\n");
357 if (of_property_read_bool(dp
, "big-endian"))
358 swap
= CFI_BIG_ENDIAN
;
359 else if (of_property_read_bool(dp
, "little-endian"))
360 swap
= CFI_LITTLE_ENDIAN
;
362 for (i
= 0; i
< info
->nmaps
; i
++) {
363 info
->maps
[i
].name
= mtd_name
;
364 info
->maps
[i
].swap
= swap
;
365 info
->maps
[i
].bankwidth
= bankwidth
;
366 info
->maps
[i
].device_node
= dp
;
368 err
= of_flash_probe_bt1_rom(dev
, dp
, &info
->maps
[i
]);
372 err
= of_flash_probe_gemini(dev
, dp
, &info
->maps
[i
]);
376 err
= of_flash_probe_ixp4xx(dev
, dp
, &info
->maps
[i
]);
380 err
= of_flash_probe_versatile(dev
, dp
, &info
->maps
[i
]);
385 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
386 * may cause problems with JFFS2 usage, as the local bus (LPB)
387 * doesn't support unaligned accesses as implemented in the
388 * JFFS2 code via memcpy(). By setting NO_XIP, the
389 * flash will not be exposed directly to the MTD users
390 * (e.g. JFFS2) any more.
393 info
->maps
[i
].phys
= NO_XIP
;
398 #else /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
399 #define of_flash_match NULL
401 static int physmap_flash_of_init(struct platform_device
*dev
)
405 #endif /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
407 static const char * const rom_probe_types
[] = {
408 "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom",
411 static const char * const part_probe_types
[] = {
412 "cmdlinepart", "RedBoot", "afs", NULL
415 static int physmap_flash_pdata_init(struct platform_device
*dev
)
417 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
418 struct physmap_flash_data
*physmap_data
;
422 physmap_data
= dev_get_platdata(&dev
->dev
);
426 info
->probe_type
= physmap_data
->probe_type
;
427 info
->part_types
= physmap_data
->part_probe_types
? : part_probe_types
;
428 info
->parts
= physmap_data
->parts
;
429 info
->nparts
= physmap_data
->nr_parts
;
431 if (physmap_data
->init
) {
432 err
= physmap_data
->init(dev
);
437 for (i
= 0; i
< info
->nmaps
; i
++) {
438 info
->maps
[i
].bankwidth
= physmap_data
->width
;
439 info
->maps
[i
].pfow_base
= physmap_data
->pfow_base
;
440 info
->maps
[i
].set_vpp
= physmap_set_vpp
;
446 static int physmap_flash_probe(struct platform_device
*dev
)
448 struct physmap_flash_info
*info
;
452 if (!dev
->dev
.of_node
&& !dev_get_platdata(&dev
->dev
))
455 info
= devm_kzalloc(&dev
->dev
, sizeof(*info
), GFP_KERNEL
);
459 while (platform_get_resource(dev
, IORESOURCE_MEM
, info
->nmaps
))
465 info
->maps
= devm_kzalloc(&dev
->dev
,
466 sizeof(*info
->maps
) * info
->nmaps
,
471 info
->mtds
= devm_kzalloc(&dev
->dev
,
472 sizeof(*info
->mtds
) * info
->nmaps
,
477 platform_set_drvdata(dev
, info
);
479 info
->gpios
= devm_gpiod_get_array_optional(&dev
->dev
, "addr",
481 if (IS_ERR(info
->gpios
))
482 return PTR_ERR(info
->gpios
);
484 if (info
->gpios
&& info
->nmaps
> 1) {
485 dev_err(&dev
->dev
, "addr-gpios only supported for nmaps == 1\n");
489 pm_runtime_enable(&dev
->dev
);
490 pm_runtime_get_sync(&dev
->dev
);
492 if (dev
->dev
.of_node
)
493 err
= physmap_flash_of_init(dev
);
495 err
= physmap_flash_pdata_init(dev
);
498 pm_runtime_put(&dev
->dev
);
499 pm_runtime_disable(&dev
->dev
);
503 for (i
= 0; i
< info
->nmaps
; i
++) {
504 struct resource
*res
;
506 info
->maps
[i
].virt
= devm_platform_get_and_ioremap_resource(dev
, i
, &res
);
507 if (IS_ERR(info
->maps
[i
].virt
)) {
508 err
= PTR_ERR(info
->maps
[i
].virt
);
512 dev_notice(&dev
->dev
, "physmap platform flash device: %pR\n",
515 if (!info
->maps
[i
].name
)
516 info
->maps
[i
].name
= dev_name(&dev
->dev
);
518 if (!info
->maps
[i
].phys
)
519 info
->maps
[i
].phys
= res
->start
;
521 info
->win_order
= fls64(resource_size(res
)) - 1;
522 info
->maps
[i
].size
= BIT(info
->win_order
+
524 info
->gpios
->ndescs
: 0));
526 info
->maps
[i
].map_priv_1
= (unsigned long)dev
;
529 err
= physmap_addr_gpios_map_init(&info
->maps
[i
]);
534 #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
536 * Only use the simple_map implementation if map hooks are not
537 * implemented. Since map->read() is mandatory checking for its
538 * presence is enough.
540 if (!info
->maps
[i
].read
)
541 simple_map_init(&info
->maps
[i
]);
543 simple_map_init(&info
->maps
[i
]);
546 if (info
->probe_type
) {
547 info
->mtds
[i
] = do_map_probe(info
->probe_type
,
550 /* Fall back to mapping region as ROM */
551 if (!info
->mtds
[i
] && IS_ENABLED(CONFIG_MTD_ROM
) &&
552 strcmp(info
->probe_type
, "map_rom")) {
554 "map_probe() failed for type %s\n",
557 info
->mtds
[i
] = do_map_probe("map_rom",
563 for (j
= 0; j
< ARRAY_SIZE(rom_probe_types
); j
++) {
564 info
->mtds
[i
] = do_map_probe(rom_probe_types
[j
],
571 if (!info
->mtds
[i
]) {
572 dev_err(&dev
->dev
, "map_probe failed\n");
576 info
->mtds
[i
]->dev
.parent
= &dev
->dev
;
579 if (info
->nmaps
== 1) {
580 info
->cmtd
= info
->mtds
[0];
583 * We detected multiple devices. Concatenate them together.
585 info
->cmtd
= mtd_concat_create(info
->mtds
, info
->nmaps
,
586 dev_name(&dev
->dev
));
593 spin_lock_init(&info
->vpp_lock
);
595 mtd_set_of_node(info
->cmtd
, dev
->dev
.of_node
);
596 err
= mtd_device_parse_register(info
->cmtd
, info
->part_types
, NULL
,
597 info
->parts
, info
->nparts
);
604 physmap_flash_remove(dev
);
609 static void physmap_flash_shutdown(struct platform_device
*dev
)
611 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
614 for (i
= 0; i
< info
->nmaps
&& info
->mtds
[i
]; i
++)
615 if (mtd_suspend(info
->mtds
[i
]) == 0)
616 mtd_resume(info
->mtds
[i
]);
619 #define physmap_flash_shutdown NULL
622 static struct platform_driver physmap_flash_driver
= {
623 .probe
= physmap_flash_probe
,
624 .remove
= physmap_flash_remove
,
625 .shutdown
= physmap_flash_shutdown
,
627 .name
= "physmap-flash",
628 .of_match_table
= of_flash_match
,
632 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
633 static struct physmap_flash_data physmap_flash_data
= {
634 .width
= CONFIG_MTD_PHYSMAP_BANKWIDTH
,
637 static struct resource physmap_flash_resource
= {
638 .start
= CONFIG_MTD_PHYSMAP_START
,
639 .end
= CONFIG_MTD_PHYSMAP_START
+ CONFIG_MTD_PHYSMAP_LEN
- 1,
640 .flags
= IORESOURCE_MEM
,
643 static struct platform_device physmap_flash
= {
644 .name
= "physmap-flash",
647 .platform_data
= &physmap_flash_data
,
650 .resource
= &physmap_flash_resource
,
654 static int __init
physmap_init(void)
658 err
= platform_driver_register(&physmap_flash_driver
);
659 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
661 err
= platform_device_register(&physmap_flash
);
663 platform_driver_unregister(&physmap_flash_driver
);
670 static void __exit
physmap_exit(void)
672 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
673 platform_device_unregister(&physmap_flash
);
675 platform_driver_unregister(&physmap_flash_driver
);
678 module_init(physmap_init
);
679 module_exit(physmap_exit
);
681 MODULE_LICENSE("GPL");
682 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
683 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
684 MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
685 MODULE_DESCRIPTION("Generic configurable MTD map driver");
687 /* legacy platform drivers can't hotplug or coldplg */
688 #ifndef CONFIG_MTD_PHYSMAP_COMPAT
689 /* work with hotplug and coldplug */
690 MODULE_ALIAS("platform:physmap-flash");