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-gemini.h"
45 #include "physmap-ixp4xx.h"
46 #include "physmap-versatile.h"
48 struct physmap_flash_info
{
50 struct mtd_info
**mtds
;
51 struct mtd_info
*cmtd
;
52 struct map_info
*maps
;
55 const char *probe_type
;
56 const char * const *part_types
;
58 const struct mtd_partition
*parts
;
59 struct gpio_descs
*gpios
;
60 unsigned int gpio_values
;
61 unsigned int win_order
;
64 static int physmap_flash_remove(struct platform_device
*dev
)
66 struct physmap_flash_info
*info
;
67 struct physmap_flash_data
*physmap_data
;
70 info
= platform_get_drvdata(dev
);
75 err
= mtd_device_unregister(info
->cmtd
);
79 if (info
->cmtd
!= info
->mtds
[0])
80 mtd_concat_destroy(info
->cmtd
);
83 for (i
= 0; i
< info
->nmaps
; i
++) {
85 map_destroy(info
->mtds
[i
]);
88 physmap_data
= dev_get_platdata(&dev
->dev
);
89 if (physmap_data
&& physmap_data
->exit
)
90 physmap_data
->exit(dev
);
93 pm_runtime_put(&dev
->dev
);
94 pm_runtime_disable(&dev
->dev
);
98 static void physmap_set_vpp(struct map_info
*map
, int state
)
100 struct platform_device
*pdev
;
101 struct physmap_flash_data
*physmap_data
;
102 struct physmap_flash_info
*info
;
105 pdev
= (struct platform_device
*)map
->map_priv_1
;
106 physmap_data
= dev_get_platdata(&pdev
->dev
);
108 if (!physmap_data
->set_vpp
)
111 info
= platform_get_drvdata(pdev
);
113 spin_lock_irqsave(&info
->vpp_lock
, flags
);
115 if (++info
->vpp_refcnt
== 1) /* first nested 'on' */
116 physmap_data
->set_vpp(pdev
, 1);
118 if (--info
->vpp_refcnt
== 0) /* last nested 'off' */
119 physmap_data
->set_vpp(pdev
, 0);
121 spin_unlock_irqrestore(&info
->vpp_lock
, flags
);
124 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_GPIO_ADDR)
125 static void physmap_set_addr_gpios(struct physmap_flash_info
*info
,
130 ofs
>>= info
->win_order
;
131 if (info
->gpio_values
== ofs
)
134 for (i
= 0; i
< info
->gpios
->ndescs
; i
++) {
135 if ((BIT(i
) & ofs
) == (BIT(i
) & info
->gpio_values
))
138 gpiod_set_value(info
->gpios
->desc
[i
], !!(BIT(i
) & ofs
));
141 info
->gpio_values
= ofs
;
144 #define win_mask(order) (BIT(order) - 1)
146 static map_word
physmap_addr_gpios_read(struct map_info
*map
,
149 struct platform_device
*pdev
;
150 struct physmap_flash_info
*info
;
154 pdev
= (struct platform_device
*)map
->map_priv_1
;
155 info
= platform_get_drvdata(pdev
);
156 physmap_set_addr_gpios(info
, ofs
);
158 word
= readw(map
->virt
+ (ofs
& win_mask(info
->win_order
)));
163 static void physmap_addr_gpios_copy_from(struct map_info
*map
, void *buf
,
164 unsigned long ofs
, ssize_t len
)
166 struct platform_device
*pdev
;
167 struct physmap_flash_info
*info
;
169 pdev
= (struct platform_device
*)map
->map_priv_1
;
170 info
= platform_get_drvdata(pdev
);
173 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
174 unsigned int chunklen
= min_t(unsigned int, len
,
175 BIT(info
->win_order
) - winofs
);
177 physmap_set_addr_gpios(info
, ofs
);
178 memcpy_fromio(buf
, map
->virt
+ winofs
, chunklen
);
185 static void physmap_addr_gpios_write(struct map_info
*map
, map_word mw
,
188 struct platform_device
*pdev
;
189 struct physmap_flash_info
*info
;
192 pdev
= (struct platform_device
*)map
->map_priv_1
;
193 info
= platform_get_drvdata(pdev
);
194 physmap_set_addr_gpios(info
, ofs
);
197 writew(word
, map
->virt
+ (ofs
& win_mask(info
->win_order
)));
200 static void physmap_addr_gpios_copy_to(struct map_info
*map
, unsigned long ofs
,
201 const void *buf
, ssize_t len
)
203 struct platform_device
*pdev
;
204 struct physmap_flash_info
*info
;
206 pdev
= (struct platform_device
*)map
->map_priv_1
;
207 info
= platform_get_drvdata(pdev
);
210 unsigned int winofs
= ofs
& win_mask(info
->win_order
);
211 unsigned int chunklen
= min_t(unsigned int, len
,
212 BIT(info
->win_order
) - winofs
);
214 physmap_set_addr_gpios(info
, ofs
);
215 memcpy_toio(map
->virt
+ winofs
, buf
, chunklen
);
222 static int physmap_addr_gpios_map_init(struct map_info
*map
)
225 map
->read
= physmap_addr_gpios_read
;
226 map
->copy_from
= physmap_addr_gpios_copy_from
;
227 map
->write
= physmap_addr_gpios_write
;
228 map
->copy_to
= physmap_addr_gpios_copy_to
;
233 static int physmap_addr_gpios_map_init(struct map_info
*map
)
239 #if IS_ENABLED(CONFIG_MTD_PHYSMAP_OF)
240 static const struct of_device_id of_flash_match
[] = {
242 .compatible
= "cfi-flash",
247 * FIXME: JEDEC chips can't be safely and reliably
248 * probed, although the mtd code gets it right in
249 * practice most of the time. We should use the
250 * vendor and device ids specified by the binding to
251 * bypass the heuristic probe code, but the mtd layer
252 * provides, at present, no interface for doing so
255 .compatible
= "jedec-flash",
256 .data
= "jedec_probe",
259 .compatible
= "mtd-ram",
263 .compatible
= "mtd-rom",
268 .compatible
= "direct-mapped"
272 MODULE_DEVICE_TABLE(of
, of_flash_match
);
274 static const char * const of_default_part_probes
[] = {
275 "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL
278 static const char * const *of_get_part_probes(struct platform_device
*dev
)
280 struct device_node
*dp
= dev
->dev
.of_node
;
284 count
= of_property_count_strings(dp
, "linux,part-probe");
286 return of_default_part_probes
;
288 res
= devm_kcalloc(&dev
->dev
, count
+ 1, sizeof(*res
), GFP_KERNEL
);
292 count
= of_property_read_string_array(dp
, "linux,part-probe", res
,
300 static const char *of_select_probe_type(struct platform_device
*dev
)
302 struct device_node
*dp
= dev
->dev
.of_node
;
303 const struct of_device_id
*match
;
304 const char *probe_type
;
306 match
= of_match_device(of_flash_match
, &dev
->dev
);
307 probe_type
= match
->data
;
312 "Device tree uses obsolete \"direct-mapped\" flash binding\n");
314 of_property_read_string(dp
, "probe-type", &probe_type
);
318 if (!strcmp(probe_type
, "CFI")) {
319 probe_type
= "cfi_probe";
320 } else if (!strcmp(probe_type
, "JEDEC")) {
321 probe_type
= "jedec_probe";
322 } else if (!strcmp(probe_type
, "ROM")) {
323 probe_type
= "map_rom";
326 "obsolete_probe: don't know probe type '%s', mapping as rom\n",
328 probe_type
= "map_rom";
334 static int physmap_flash_of_init(struct platform_device
*dev
)
336 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
337 struct device_node
*dp
= dev
->dev
.of_node
;
338 const char *mtd_name
= NULL
;
347 info
->probe_type
= of_select_probe_type(dev
);
349 info
->part_types
= of_get_part_probes(dev
);
350 if (!info
->part_types
)
353 of_property_read_string(dp
, "linux,mtd-name", &mtd_name
);
355 map_indirect
= of_property_read_bool(dp
, "no-unaligned-direct-access");
357 err
= of_property_read_u32(dp
, "bank-width", &bankwidth
);
359 dev_err(&dev
->dev
, "Can't get bank width from device tree\n");
363 if (of_property_read_bool(dp
, "big-endian"))
364 swap
= CFI_BIG_ENDIAN
;
365 else if (of_property_read_bool(dp
, "little-endian"))
366 swap
= CFI_LITTLE_ENDIAN
;
368 for (i
= 0; i
< info
->nmaps
; i
++) {
369 info
->maps
[i
].name
= mtd_name
;
370 info
->maps
[i
].swap
= swap
;
371 info
->maps
[i
].bankwidth
= bankwidth
;
372 info
->maps
[i
].device_node
= dp
;
374 err
= of_flash_probe_gemini(dev
, dp
, &info
->maps
[i
]);
378 err
= of_flash_probe_ixp4xx(dev
, dp
, &info
->maps
[i
]);
382 err
= of_flash_probe_versatile(dev
, dp
, &info
->maps
[i
]);
387 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
388 * may cause problems with JFFS2 usage, as the local bus (LPB)
389 * doesn't support unaligned accesses as implemented in the
390 * JFFS2 code via memcpy(). By setting NO_XIP, the
391 * flash will not be exposed directly to the MTD users
392 * (e.g. JFFS2) any more.
395 info
->maps
[i
].phys
= NO_XIP
;
400 #else /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
401 #define of_flash_match NULL
403 static int physmap_flash_of_init(struct platform_device
*dev
)
407 #endif /* IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) */
409 static const char * const rom_probe_types
[] = {
410 "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom",
413 static const char * const part_probe_types
[] = {
414 "cmdlinepart", "RedBoot", "afs", NULL
417 static int physmap_flash_pdata_init(struct platform_device
*dev
)
419 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
420 struct physmap_flash_data
*physmap_data
;
424 physmap_data
= dev_get_platdata(&dev
->dev
);
428 info
->probe_type
= physmap_data
->probe_type
;
429 info
->part_types
= physmap_data
->part_probe_types
? : part_probe_types
;
430 info
->parts
= physmap_data
->parts
;
431 info
->nparts
= physmap_data
->nr_parts
;
433 if (physmap_data
->init
) {
434 err
= physmap_data
->init(dev
);
439 for (i
= 0; i
< info
->nmaps
; i
++) {
440 info
->maps
[i
].bankwidth
= physmap_data
->width
;
441 info
->maps
[i
].pfow_base
= physmap_data
->pfow_base
;
442 info
->maps
[i
].set_vpp
= physmap_set_vpp
;
448 static int physmap_flash_probe(struct platform_device
*dev
)
450 struct physmap_flash_info
*info
;
454 if (!dev
->dev
.of_node
&& !dev_get_platdata(&dev
->dev
))
457 info
= devm_kzalloc(&dev
->dev
, sizeof(*info
), GFP_KERNEL
);
461 while (platform_get_resource(dev
, IORESOURCE_MEM
, info
->nmaps
))
467 info
->maps
= devm_kzalloc(&dev
->dev
,
468 sizeof(*info
->maps
) * info
->nmaps
,
473 info
->mtds
= devm_kzalloc(&dev
->dev
,
474 sizeof(*info
->mtds
) * info
->nmaps
,
479 platform_set_drvdata(dev
, info
);
481 info
->gpios
= devm_gpiod_get_array_optional(&dev
->dev
, "addr",
483 if (IS_ERR(info
->gpios
))
484 return PTR_ERR(info
->gpios
);
486 if (info
->gpios
&& info
->nmaps
> 1) {
487 dev_err(&dev
->dev
, "addr-gpios only supported for nmaps == 1\n");
491 pm_runtime_enable(&dev
->dev
);
492 pm_runtime_get_sync(&dev
->dev
);
494 if (dev
->dev
.of_node
)
495 err
= physmap_flash_of_init(dev
);
497 err
= physmap_flash_pdata_init(dev
);
500 pm_runtime_put(&dev
->dev
);
501 pm_runtime_disable(&dev
->dev
);
505 for (i
= 0; i
< info
->nmaps
; i
++) {
506 struct resource
*res
;
508 res
= platform_get_resource(dev
, IORESOURCE_MEM
, i
);
509 info
->maps
[i
].virt
= devm_ioremap_resource(&dev
->dev
, res
);
510 if (IS_ERR(info
->maps
[i
].virt
)) {
511 err
= PTR_ERR(info
->maps
[i
].virt
);
515 dev_notice(&dev
->dev
, "physmap platform flash device: %pR\n",
518 info
->maps
[i
].name
= dev_name(&dev
->dev
);
520 if (!info
->maps
[i
].phys
)
521 info
->maps
[i
].phys
= res
->start
;
523 info
->win_order
= get_bitmask_order(resource_size(res
)) - 1;
524 info
->maps
[i
].size
= BIT(info
->win_order
+
526 info
->gpios
->ndescs
: 0));
528 info
->maps
[i
].map_priv_1
= (unsigned long)dev
;
531 err
= physmap_addr_gpios_map_init(&info
->maps
[i
]);
536 #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
538 * Only use the simple_map implementation if map hooks are not
539 * implemented. Since map->read() is mandatory checking for its
540 * presence is enough.
542 if (!info
->maps
[i
].read
)
543 simple_map_init(&info
->maps
[i
]);
545 simple_map_init(&info
->maps
[i
]);
548 if (info
->probe_type
) {
549 info
->mtds
[i
] = do_map_probe(info
->probe_type
,
554 for (j
= 0; j
< ARRAY_SIZE(rom_probe_types
); j
++) {
555 info
->mtds
[i
] = do_map_probe(rom_probe_types
[j
],
562 if (!info
->mtds
[i
]) {
563 dev_err(&dev
->dev
, "map_probe failed\n");
567 info
->mtds
[i
]->dev
.parent
= &dev
->dev
;
570 if (info
->nmaps
== 1) {
571 info
->cmtd
= info
->mtds
[0];
574 * We detected multiple devices. Concatenate them together.
576 info
->cmtd
= mtd_concat_create(info
->mtds
, info
->nmaps
,
577 dev_name(&dev
->dev
));
584 spin_lock_init(&info
->vpp_lock
);
586 mtd_set_of_node(info
->cmtd
, dev
->dev
.of_node
);
587 err
= mtd_device_parse_register(info
->cmtd
, info
->part_types
, NULL
,
588 info
->parts
, info
->nparts
);
595 physmap_flash_remove(dev
);
600 static void physmap_flash_shutdown(struct platform_device
*dev
)
602 struct physmap_flash_info
*info
= platform_get_drvdata(dev
);
605 for (i
= 0; i
< info
->nmaps
&& info
->mtds
[i
]; i
++)
606 if (mtd_suspend(info
->mtds
[i
]) == 0)
607 mtd_resume(info
->mtds
[i
]);
610 #define physmap_flash_shutdown NULL
613 static struct platform_driver physmap_flash_driver
= {
614 .probe
= physmap_flash_probe
,
615 .remove
= physmap_flash_remove
,
616 .shutdown
= physmap_flash_shutdown
,
618 .name
= "physmap-flash",
619 .of_match_table
= of_flash_match
,
623 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
624 static struct physmap_flash_data physmap_flash_data
= {
625 .width
= CONFIG_MTD_PHYSMAP_BANKWIDTH
,
628 static struct resource physmap_flash_resource
= {
629 .start
= CONFIG_MTD_PHYSMAP_START
,
630 .end
= CONFIG_MTD_PHYSMAP_START
+ CONFIG_MTD_PHYSMAP_LEN
- 1,
631 .flags
= IORESOURCE_MEM
,
634 static struct platform_device physmap_flash
= {
635 .name
= "physmap-flash",
638 .platform_data
= &physmap_flash_data
,
641 .resource
= &physmap_flash_resource
,
645 static int __init
physmap_init(void)
649 err
= platform_driver_register(&physmap_flash_driver
);
650 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
652 err
= platform_device_register(&physmap_flash
);
654 platform_driver_unregister(&physmap_flash_driver
);
661 static void __exit
physmap_exit(void)
663 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
664 platform_device_unregister(&physmap_flash
);
666 platform_driver_unregister(&physmap_flash_driver
);
669 module_init(physmap_init
);
670 module_exit(physmap_exit
);
672 MODULE_LICENSE("GPL");
673 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
674 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
675 MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
676 MODULE_DESCRIPTION("Generic configurable MTD map driver");
678 /* legacy platform drivers can't hotplug or coldplg */
679 #ifndef CONFIG_MTD_PHYSMAP_COMPAT
680 /* work with hotplug and coldplug */
681 MODULE_ALIAS("platform:physmap-flash");