Treat device tree data in the same way as we treat ACPI tables: discover them from the EFI configuration table array, and parse the properties that describe hardware. This means we omit /chosen and the /memory nodes, which carry information that we should be receiving from EFI. not from the device tree. On the non-EFI boot path, parse the DT passed via the boot entrypoint as usual: things like bootargs, initrd and other bootloader generated data are all loaded from the DT /chosen node, along with memory descriptions and other things we would otherwise get from EFI. Note that this approach is similar to x86, which also supports FDT for hardware descriptions but not for boottime generated data. Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> --- arch/loongarch/Kconfig | 2 ++ arch/loongarch/kernel/efi.c | 14 ++++++++++++++ arch/loongarch/kernel/env.c | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 14a2a1ec8561..721b1dc38bdf 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -104,6 +104,8 @@ config LOONGARCH select MODULES_USE_ELF_RELA if MODULES select NEED_PER_CPU_EMBED_FIRST_CHUNK select NEED_PER_CPU_PAGE_FIRST_CHUNK + select OF + select OF_EARLY_FLATTREE select PCI select PCI_DOMAINS_GENERIC select PCI_ECAM if ACPI diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 3b80675726ec..96c8621da2ba 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/kobject.h> #include <linux/memblock.h> +#include <linux/of_fdt.h> #include <linux/reboot.h> #include <linux/uaccess.h> @@ -28,10 +29,12 @@ static unsigned long efi_nr_tables; static unsigned long efi_config_table; static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR; +static unsigned long __initdata boot_fdt = EFI_INVALID_TABLE_ADDR; static efi_system_table_t *efi_systab; static efi_config_table_type_t arch_tables[] __initdata = { {LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" }, + {DEVICE_TREE_GUID, &boot_fdt, "FDT" }, {}, }; @@ -100,4 +103,15 @@ void __init efi_init(void) early_memunmap(tbl, sizeof(*tbl)); } } + + if (boot_fdt != EFI_INVALID_TABLE_ADDR) { + void *tbl; + + tbl = early_memremap_ro(boot_fdt, sizeof(*tbl)); + if (tbl) { + early_init_dt_verify(tbl); + early_init_dt_scan_root(); + early_init_fdt_reserve_self(); + } + } } diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 05c38d28476e..3267063df1f9 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -8,6 +8,7 @@ #include <linux/efi.h> #include <linux/export.h> #include <linux/memblock.h> +#include <linux/of_fdt.h> #include <asm/early_ioremap.h> #include <asm/bootinfo.h> #include <asm/loongson.h> @@ -29,6 +30,11 @@ void __init init_environ(void) efi_system_table = fw_arg1; set_bit(EFI_BOOT, &efi.flags); } else { + void *fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K); + + early_init_dt_scan(fdt_ptr); + early_init_fdt_reserve_self(); + clear_bit(EFI_BOOT, &efi.flags); } } -- 2.35.1