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/mtd/mtd.h>
34 #include <linux/mtd/map.h>
35 #include <linux/mtd/partitions.h>
36 #include <linux/mtd/physmap.h>
37 #include <linux/mtd/concat.h>
38 #include <linux/mtd/cfi_endian.h>
40 #include <linux/of_device.h>
41 #include <linux/pm_runtime.h>
42 #include <linux/gpio/consumer.h>
44 #include "physmap-bt1-rom.h"
45 #include "physmap-gemini.h"
46 #include "physmap-ixp4xx.h"
47 #include "physmap-versatile.h"
49 struct physmap_flash_info
{
51 struct mtd_info
**mtds
;
52 struct mtd_info
*cmtd
;
53 struct map_info
*maps
;
56 const char *probe_type
;
57 const char * const *part_types
;
59 const struct mtd_partition
*parts
;
60 struct gpio_descs
*gpios
;
61 unsigned int gpio_values
;
62 unsigned int win_order
;
65 static int physmap_flash_remove(struct platform_device
*dev
)
67 struct physmap_flash_info
*info
;
68 struct physmap_flash_data
*physmap_data
;
71 info
= platform_get_drvdata(dev
);
76 err
= mtd_device_unregister(info
->cmtd
);
80 if (info
->cmtd
!= info
->mtds
[0])
81 mtd_concat_destroy(info
->cmtd
);
84 for (i
= 0; i
< info
->nmaps
; i
++) {
86 map_destroy(info
->mtds
[i
]);
89 physmap_data
= dev_get_platdata(&dev
->dev
);
90 if (physmap_data
&& physmap_data
->exit
)
91 physmap_data
->exit(dev
);
94 pm_runtime_put(&dev
->dev
);
95 pm_runtime_disable(&dev
->dev
);
99 static void physmap_set_vpp(struct map_info
*map
, int state
)
101 struct platform_device
*pdev
;
102 struct physmap_flash_data
*physmap_data
;
103 struct physmap_flash_info
*info
;
106 pdev
= (struct platform_device
*)map
->map_priv_1
;
107 physmap_data
= dev_get_platdata(&pdev
->dev
);
109 if (!physmap_data
->set_vpp
)
112 info
= platform_get_drvdata(pdev
);
114 spin_lock_irqsave(&info
->vpp_lock
, flags
);
116 if (++info
->vpp_refcnt
== 1) /* first nested 'on' */
117 physmap_data
->set_vpp(pdev
, 1);
119 if (--info
->vpp_refcnt
== 0) /* last nested 'off' */
120 physmap_data
->set_vpp(pdev
, 0);
122 spin_unlock_irqrestore(&info
->vpp_lock
, flags
);
125 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_GPIO_ADDR)
126 static void physmap_set_addr_gpios(struct physmap_flash_info
*info
,
131 ofs
>>= info
->win_order
;
132 if (info
->gpio_values
== ofs
)
135 for (i
= 0; i
< info
->gpios
->ndescs
; i
++) {
136 if ((BIT(i
) & ofs
) == (BIT(i
) & info
->gpio_values
))
139 gpiod_set_value(info
->gpios
->desc
[i
], !!(BIT(i
) & ofs
));
142 info
->gpio_values
= ofs
;
145 #define win_mask(order) (BIT(order) - 1)
147 static map_word
physmap_addr_gpios_read(struct map_info
*map
,
150 struct platform_device
*pdev
;
151 struct physmap_flash_info
*info
;
155 pdev
= (struct platform_device
*)map
->map_priv_1
;
156 info
= platform_get_drvdata(pdev
);
157 physmap_set_addr_gpios(info
, ofs
);
159 word
= readw(map
->virt
+ (ofs
& win_mask(info
->win_order
)));
164 static void physmap_addr_gpios_copy_from(struct map_info
*map
, void *buf
,
165 unsigned long ofs
, ssize_t len
)
167 struct platform_device
*pdev
;
168 struct physmap_flash_info
*info
;
170 pdev
= (struct platform_device
*)map
->map_priv_1
;
171 info
= platform_get_drvdata(pdev
);
174 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
175 unsigned int chunklen
= min_t(unsigned int, len
,
176 BIT(info
->win_order
) - winofs
);
178 physmap_set_addr_gpios(info
, ofs
);
179 memcpy_fromio(buf
, map
->virt
+ winofs
, chunklen
);
186 static void physmap_addr_gpios_write(struct map_info
*map
, map_word mw
,
189 struct platform_device
*pdev
;
190 struct physmap_flash_info
*info
;
193 pdev
= (struct platform_device
*)map
->map_priv_1
;
194 info
= platform_get_drvdata(pdev
);
195 physmap_set_addr_gpios(info
, ofs
);
198 writew(word
, map
->virt
+ (ofs
& win_mask(info
->win_order
)));
201 static void physmap_addr_gpios_copy_to(struct map_info
*map
, unsigned long ofs
,
202 const void *buf
, ssize_t len
)
204 struct platform_device
*pdev
;
205 struct physmap_flash_info
*info
;
207 pdev
= (struct platform_device
*)map
->map_priv_1
;
208 info
= platform_get_drvdata(pdev
);
211 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
212 unsigned int chunklen
= min_t(unsigned int, len
,
213 BIT(info
->win_order
) - winofs
);
215 physmap_set_addr_gpios(info
, ofs
);
216 memcpy_toio(map
->virt
+ winofs
, buf
, chunklen
);
223 static int physmap_addr_gpios_map_init(struct map_info
*map
)
226 map
->read
= physmap_addr_gpios_read
;
227 map
->copy_from
= physmap_addr_gpios_copy_from
;
228 map
->write
= physmap_addr_gpios_write
;
229 map
->copy_to
= physmap_addr_gpios_copy_to
;
234 static int physmap_addr_gpios_map_init(struct map_info
*map
)
240 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_OF)
241 static const struct of_device_id of_flash_match
[] = {
243 .compatible
= "cfi-flash",
248 * FIXME: JEDEC chips can't be safely and reliably
249 * probed, although the mtd code gets it right in
250 * practice most of the time. We should use the
251 * vendor and device ids specified by the binding to
252 * bypass the heuristic probe code, but the mtd layer
253 * provides, at present, no interface for doing so
256 .compatible
= "jedec-flash",
257 .data
= "jedec_probe",
260 .compatible
= "mtd-ram",
264 .compatible
= "mtd-rom",
269 .compatible
= "direct-mapped"
273 MODULE_DEVICE_TABLE(of
, of_flash_match
);
275 static const char * const of_default_part_probes
[] = {
276 "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL
279 static const char * const *of_get_part_probes(struct platform_device
*dev
)
281 struct device_node
*dp
= dev
->dev
.of_node
;
285 count
= of_property_count_strings(dp
, "linux,part-probe");
287 return of_default_part_probes
;
289 res
= devm_kcalloc(&dev
->dev
, count
+ 1, sizeof(*res
), GFP_KERNEL
);
293 count
= of_property_read_string_array(dp
, "linux,part-probe", res
,
301 static const char *of_select_probe_type(struct platform_device
*dev
)
303 struct device_node
*dp
= dev
->dev
.of_node
;
304 const struct of_device_id
*match
;
305 const char *probe_type
;
307 match
= of_match_device(of_flash_match
, &dev
->dev
);
308 probe_type
= match
->data
;
313 "Device tree uses obsolete \"direct-mapped\" flash binding\n");
315 of_property_read_string(dp
, "probe-type", &probe_type
);
319 if (!strcmp(probe_type
, "CFI")) {
320 probe_type
= "cfi_probe";
321 } else if (!strcmp(probe_type
, "JEDEC")) {
322 probe_type
= "jedec_probe";
323 } else if (!strcmp(probe_type
, "ROM")) {
324 probe_type
= "map_rom";
327 "obsolete_probe: don't know probe type '%s', mapping as rom\n",
329 probe_type
= "map_rom";
335 static int physmap_flash_of_init(struct platform_device
*dev
)
337 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
338 struct device_node
*dp
= dev
->dev
.of_node
;
339 const char *mtd_name
= NULL
;
348 info
->probe_type
= of_select_probe_type(dev
);
350 info
->part_types
= of_get_part_probes(dev
);
351 if (!info
->part_types
)
354 of_property_read_string(dp
, "linux,mtd-name", &mtd_name
);
356 map_indirect
= of_property_read_bool(dp
, "no-unaligned-direct-access");
358 err
= of_property_read_u32(dp
, "bank-width", &bankwidth
);
360 dev_err(&dev
->dev
, "Can't get bank width from device tree\n");
364 if (of_property_read_bool(dp
, "big-endian"))
365 swap
= CFI_BIG_ENDIAN
;
366 else if (of_property_read_bool(dp
, "little-endian"))
367 swap
= CFI_LITTLE_ENDIAN
;
369 for (i
= 0; i
< info
->nmaps
; i
++) {
370 info
->maps
[i
].name
= mtd_name
;
371 info
->maps
[i
].swap
= swap
;
372 info
->maps
[i
].bankwidth
= bankwidth
;
373 info
->maps
[i
].device_node
= dp
;
375 err
= of_flash_probe_bt1_rom(dev
, dp
, &info
->maps
[i
]);
379 err
= of_flash_probe_gemini(dev
, dp
, &info
->maps
[i
]);
383 err
= of_flash_probe_ixp4xx(dev
, dp
, &info
->maps
[i
]);
387 err
= of_flash_probe_versatile(dev
, dp
, &info
->maps
[i
]);
392 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
393 * may cause problems with JFFS2 usage, as the local bus (LPB)
394 * doesn't support unaligned accesses as implemented in the
395 * JFFS2 code via memcpy(). By setting NO_XIP, the
396 * flash will not be exposed directly to the MTD users
397 * (e.g. JFFS2) any more.
400 info
->maps
[i
].phys
= NO_XIP
;
405 #else /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
406 #define of_flash_match NULL
408 static int physmap_flash_of_init(struct platform_device
*dev
)
412 #endif /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
414 static const char * const rom_probe_types
[] = {
415 "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom",
418 static const char * const part_probe_types
[] = {
419 "cmdlinepart", "RedBoot", "afs", NULL
422 static int physmap_flash_pdata_init(struct platform_device
*dev
)
424 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
425 struct physmap_flash_data
*physmap_data
;
429 physmap_data
= dev_get_platdata(&dev
->dev
);
433 info
->probe_type
= physmap_data
->probe_type
;
434 info
->part_types
= physmap_data
->part_probe_types
? : part_probe_types
;
435 info
->parts
= physmap_data
->parts
;
436 info
->nparts
= physmap_data
->nr_parts
;
438 if (physmap_data
->init
) {
439 err
= physmap_data
->init(dev
);
444 for (i
= 0; i
< info
->nmaps
; i
++) {
445 info
->maps
[i
].bankwidth
= physmap_data
->width
;
446 info
->maps
[i
].pfow_base
= physmap_data
->pfow_base
;
447 info
->maps
[i
].set_vpp
= physmap_set_vpp
;
453 static int physmap_flash_probe(struct platform_device
*dev
)
455 struct physmap_flash_info
*info
;
459 if (!dev
->dev
.of_node
&& !dev_get_platdata(&dev
->dev
))
462 info
= devm_kzalloc(&dev
->dev
, sizeof(*info
), GFP_KERNEL
);
466 while (platform_get_resource(dev
, IORESOURCE_MEM
, info
->nmaps
))
472 info
->maps
= devm_kzalloc(&dev
->dev
,
473 sizeof(*info
->maps
) * info
->nmaps
,
478 info
->mtds
= devm_kzalloc(&dev
->dev
,
479 sizeof(*info
->mtds
) * info
->nmaps
,
484 platform_set_drvdata(dev
, info
);
486 info
->gpios
= devm_gpiod_get_array_optional(&dev
->dev
, "addr",
488 if (IS_ERR(info
->gpios
))
489 return PTR_ERR(info
->gpios
);
491 if (info
->gpios
&& info
->nmaps
> 1) {
492 dev_err(&dev
->dev
, "addr-gpios only supported for nmaps == 1\n");
496 pm_runtime_enable(&dev
->dev
);
497 pm_runtime_get_sync(&dev
->dev
);
499 if (dev
->dev
.of_node
)
500 err
= physmap_flash_of_init(dev
);
502 err
= physmap_flash_pdata_init(dev
);
505 pm_runtime_put(&dev
->dev
);
506 pm_runtime_disable(&dev
->dev
);
510 for (i
= 0; i
< info
->nmaps
; i
++) {
511 struct resource
*res
;
513 res
= platform_get_resource(dev
, IORESOURCE_MEM
, i
);
514 info
->maps
[i
].virt
= devm_ioremap_resource(&dev
->dev
, res
);
515 if (IS_ERR(info
->maps
[i
].virt
)) {
516 err
= PTR_ERR(info
->maps
[i
].virt
);
520 dev_notice(&dev
->dev
, "physmap platform flash device: %pR\n",
523 if (!info
->maps
[i
].name
)
524 info
->maps
[i
].name
= dev_name(&dev
->dev
);
526 if (!info
->maps
[i
].phys
)
527 info
->maps
[i
].phys
= res
->start
;
529 info
->win_order
= get_bitmask_order(resource_size(res
)) - 1;
530 info
->maps
[i
].size
= BIT(info
->win_order
+
532 info
->gpios
->ndescs
: 0));
534 info
->maps
[i
].map_priv_1
= (unsigned long)dev
;
537 err
= physmap_addr_gpios_map_init(&info
->maps
[i
]);
542 #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
544 * Only use the simple_map implementation if map hooks are not
545 * implemented. Since map->read() is mandatory checking for its
546 * presence is enough.
548 if (!info
->maps
[i
].read
)
549 simple_map_init(&info
->maps
[i
]);
551 simple_map_init(&info
->maps
[i
]);
554 if (info
->probe_type
) {
555 info
->mtds
[i
] = do_map_probe(info
->probe_type
,
560 for (j
= 0; j
< ARRAY_SIZE(rom_probe_types
); j
++) {
561 info
->mtds
[i
] = do_map_probe(rom_probe_types
[j
],
568 if (!info
->mtds
[i
]) {
569 dev_err(&dev
->dev
, "map_probe failed\n");
573 info
->mtds
[i
]->dev
.parent
= &dev
->dev
;
576 if (info
->nmaps
== 1) {
577 info
->cmtd
= info
->mtds
[0];
580 * We detected multiple devices. Concatenate them together.
582 info
->cmtd
= mtd_concat_create(info
->mtds
, info
->nmaps
,
583 dev_name(&dev
->dev
));
590 spin_lock_init(&info
->vpp_lock
);
592 mtd_set_of_node(info
->cmtd
, dev
->dev
.of_node
);
593 err
= mtd_device_parse_register(info
->cmtd
, info
->part_types
, NULL
,
594 info
->parts
, info
->nparts
);
601 physmap_flash_remove(dev
);
606 static void physmap_flash_shutdown(struct platform_device
*dev
)
608 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
611 for (i
= 0; i
< info
->nmaps
&& info
->mtds
[i
]; i
++)
612 if (mtd_suspend(info
->mtds
[i
]) == 0)
613 mtd_resume(info
->mtds
[i
]);
616 #define physmap_flash_shutdown NULL
619 static struct platform_driver physmap_flash_driver
= {
620 .probe
= physmap_flash_probe
,
621 .remove
= physmap_flash_remove
,
622 .shutdown
= physmap_flash_shutdown
,
624 .name
= "physmap-flash",
625 .of_match_table
= of_flash_match
,
629 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
630 static struct physmap_flash_data physmap_flash_data
= {
631 .width
= CONFIG_MTD_PHYSMAP_BANKWIDTH
,
634 static struct resource physmap_flash_resource
= {
635 .start
= CONFIG_MTD_PHYSMAP_START
,
636 .end
= CONFIG_MTD_PHYSMAP_START
+ CONFIG_MTD_PHYSMAP_LEN
- 1,
637 .flags
= IORESOURCE_MEM
,
640 static struct platform_device physmap_flash
= {
641 .name
= "physmap-flash",
644 .platform_data
= &physmap_flash_data
,
647 .resource
= &physmap_flash_resource
,
651 static int __init
physmap_init(void)
655 err
= platform_driver_register(&physmap_flash_driver
);
656 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
658 err
= platform_device_register(&physmap_flash
);
660 platform_driver_unregister(&physmap_flash_driver
);
667 static void __exit
physmap_exit(void)
669 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
670 platform_device_unregister(&physmap_flash
);
672 platform_driver_unregister(&physmap_flash_driver
);
675 module_init(physmap_init
);
676 module_exit(physmap_exit
);
678 MODULE_LICENSE("GPL");
679 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
680 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
681 MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
682 MODULE_DESCRIPTION("Generic configurable MTD map driver");
684 /* legacy platform drivers can't hotplug or coldplg */
685 #ifndef CONFIG_MTD_PHYSMAP_COMPAT
686 /* work with hotplug and coldplug */
687 MODULE_ALIAS("platform:physmap-flash");