Skip to content

Commit 7b937cc

Browse files
frowandrobherring
authored andcommitted
of: Create of_root if no dtb provided by firmware
When enabling CONFIG_OF on a platform where 'of_root' is not populated by firmware, we end up without a root node. In order to apply overlays and create subnodes of the root node, we need one. Create this root node by unflattening an empty builtin dtb. If firmware provides a flattened device tree (FDT) then the FDT is unflattened via setup_arch(). Otherwise, the call to unflatten(_and_copy)?_device_tree() will create an empty root node. We make of_have_populated_dt() return true only if the DTB was loaded by firmware so that existing callers don't change behavior after this patch. The call in the of platform code is removed because it prevents overlays from creating platform devices when the empty root node is used. [[email protected]: Update of_have_populated_dt() to treat this empty dtb as not populated. Drop setup_of() initcall] Signed-off-by: Frank Rowand <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: Rob Herring <[email protected]> Signed-off-by: Stephen Boyd <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rob Herring <[email protected]>
1 parent dc1460f commit 7b937cc

File tree

6 files changed

+55
-18
lines changed

6 files changed

+55
-18
lines changed

drivers/of/Kconfig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ if OF
1414

1515
config OF_UNITTEST
1616
bool "Device Tree runtime unit tests"
17-
depends on !SPARC
17+
depends on OF_EARLY_FLATTREE
1818
select IRQ_DOMAIN
19-
select OF_EARLY_FLATTREE
2019
select OF_RESOLVE
2120
help
2221
This option builds in test cases for the device tree infrastructure
@@ -54,7 +53,7 @@ config OF_FLATTREE
5453
select CRC32
5554

5655
config OF_EARLY_FLATTREE
57-
bool
56+
def_bool OF && !(SPARC || ALPHA || HEXAGON || M68K || PARISC || S390)
5857
select DMA_DECLARE_COHERENT if HAS_DMA && HAS_IOMEM
5958
select OF_FLATTREE
6059

drivers/of/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
obj-y = base.o cpu.o device.o module.o platform.o property.o
33
obj-$(CONFIG_OF_KOBJ) += kobj.o
44
obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
5-
obj-$(CONFIG_OF_FLATTREE) += fdt.o
5+
obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o
66
obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
77
obj-$(CONFIG_OF_PROMTREE) += pdt.o
88
obj-$(CONFIG_OF_ADDRESS) += address.o

drivers/of/empty_root.dts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/dts-v1/;
3+
4+
/ {
5+
6+
};

drivers/of/fdt.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#define pr_fmt(fmt) "OF: fdt: " fmt
1010

11+
#include <linux/acpi.h>
1112
#include <linux/crash_dump.h>
1213
#include <linux/crc32.h>
1314
#include <linux/kernel.h>
@@ -32,6 +33,13 @@
3233

3334
#include "of_private.h"
3435

36+
/*
37+
* __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by
38+
* cmd_dt_S_dtb in scripts/Makefile.lib
39+
*/
40+
extern uint8_t __dtb_empty_root_begin[];
41+
extern uint8_t __dtb_empty_root_end[];
42+
3543
/*
3644
* of_fdt_limit_memory - limit the number of regions in the /memory node
3745
* @limit: maximum entries
@@ -1343,7 +1351,29 @@ static void *__init copy_device_tree(void *fdt)
13431351
*/
13441352
void __init unflatten_device_tree(void)
13451353
{
1346-
__unflatten_device_tree(initial_boot_params, NULL, &of_root,
1354+
void *fdt = initial_boot_params;
1355+
1356+
/* Don't use the bootloader provided DTB if ACPI is enabled */
1357+
if (!acpi_disabled)
1358+
fdt = NULL;
1359+
1360+
/*
1361+
* Populate an empty root node when ACPI is enabled or bootloader
1362+
* doesn't provide one.
1363+
*/
1364+
if (!fdt) {
1365+
fdt = (void *) __dtb_empty_root_begin;
1366+
/* fdt_totalsize() will be used for copy size */
1367+
if (fdt_totalsize(fdt) >
1368+
__dtb_empty_root_end - __dtb_empty_root_begin) {
1369+
pr_err("invalid size in dtb_empty_root\n");
1370+
return;
1371+
}
1372+
of_fdt_crc32 = crc32_be(~0, fdt, fdt_totalsize(fdt));
1373+
fdt = copy_device_tree(fdt);
1374+
}
1375+
1376+
__unflatten_device_tree(fdt, NULL, &of_root,
13471377
early_init_dt_alloc_memory_arch, false);
13481378

13491379
/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */

drivers/of/platform.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,6 @@ static int __init of_platform_default_populate_init(void)
512512

513513
device_links_supplier_sync_state_pause();
514514

515-
if (!of_have_populated_dt())
516-
return -ENODEV;
517-
518515
if (IS_ENABLED(CONFIG_PPC)) {
519516
struct device_node *boot_display = NULL;
520517
struct platform_device *dev;

include/linux/of.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,6 @@ static inline bool is_of_node(const struct fwnode_handle *fwnode)
180180
&__of_fwnode_handle_node->fwnode : NULL; \
181181
})
182182

183-
static inline bool of_have_populated_dt(void)
184-
{
185-
return of_root != NULL;
186-
}
187-
188183
static inline bool of_node_is_root(const struct device_node *node)
189184
{
190185
return node && (node->parent == NULL);
@@ -546,11 +541,6 @@ static inline struct device_node *of_find_node_with_property(
546541

547542
#define of_fwnode_handle(node) NULL
548543

549-
static inline bool of_have_populated_dt(void)
550-
{
551-
return false;
552-
}
553-
554544
static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
555545
const char *compatible)
556546
{
@@ -1634,6 +1624,21 @@ static inline bool of_device_is_system_power_controller(const struct device_node
16341624
return of_property_read_bool(np, "system-power-controller");
16351625
}
16361626

1627+
/**
1628+
* of_have_populated_dt() - Has DT been populated by bootloader
1629+
*
1630+
* Return: True if a DTB has been populated by the bootloader and it isn't the
1631+
* empty builtin one. False otherwise.
1632+
*/
1633+
static inline bool of_have_populated_dt(void)
1634+
{
1635+
#ifdef CONFIG_OF
1636+
return of_property_present(of_root, "compatible");
1637+
#else
1638+
return false;
1639+
#endif
1640+
}
1641+
16371642
/*
16381643
* Overlay support
16391644
*/

0 commit comments

Comments
 (0)