Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mips: generic: add fdt fixup for Realtek reference board

The bootloader used on the Realtek RTL9302C boards is an ancient vendor
fork of U-Boot that doesn't understand device trees. So to run a modern
kernel it is necessary use one of the APPENDED_DTB options.

When appending the DTB the inintrd information, if present, needs to be
inserted into the /chosen device tree node. The bootloader provides the
initrd start/size via the firmware environment. Add a fdt fixup that
will update the device tree with the initrd information.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

Chris Packham and committed by
Thomas Bogendoerfer
662c0002 62b8db3a

+80
+1
arch/mips/generic/Makefile
··· 13 13 obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o 14 14 obj-$(CONFIG_MACH_INGENIC) += board-ingenic.o 15 15 obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o 16 + obj-$(CONFIG_MACH_REALTEK_RTL) += board-realtek.o
+79
arch/mips/generic/board-realtek.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2024 Allied Telesis 4 + */ 5 + 6 + #include <linux/errno.h> 7 + #include <linux/libfdt.h> 8 + #include <linux/printk.h> 9 + #include <linux/types.h> 10 + 11 + #include <asm/fw/fw.h> 12 + #include <asm/machine.h> 13 + 14 + static __init int realtek_add_initrd(void *fdt) 15 + { 16 + int node, err; 17 + u32 start, size; 18 + 19 + node = fdt_path_offset(fdt, "/chosen"); 20 + if (node < 0) { 21 + pr_err("/chosen node not found\n"); 22 + return -ENOENT; 23 + } 24 + 25 + start = fw_getenvl("initrd_start"); 26 + size = fw_getenvl("initrd_size"); 27 + 28 + if (start == 0 && size == 0) 29 + return 0; 30 + 31 + pr_info("Adding initrd info from environment\n"); 32 + 33 + err = fdt_setprop_u32(fdt, node, "linux,initrd-start", start); 34 + if (err) { 35 + pr_err("unable to set initrd-start: %d\n", err); 36 + return err; 37 + } 38 + 39 + err = fdt_setprop_u32(fdt, node, "linux,initrd-end", start + size); 40 + if (err) { 41 + pr_err("unable to set initrd-end: %d\n", err); 42 + return err; 43 + } 44 + 45 + return 0; 46 + } 47 + 48 + static const struct mips_fdt_fixup realtek_fdt_fixups[] __initconst = { 49 + { realtek_add_initrd, "add initrd" }, 50 + {}, 51 + }; 52 + 53 + static __init const void *realtek_fixup_fdt(const void *fdt, const void *match_data) 54 + { 55 + static unsigned char fdt_buf[16 << 10] __initdata; 56 + int err; 57 + 58 + if (fdt_check_header(fdt)) 59 + panic("Corrupt DT"); 60 + 61 + fw_init_cmdline(); 62 + 63 + err = apply_mips_fdt_fixups(fdt_buf, sizeof(fdt_buf), fdt, realtek_fdt_fixups); 64 + if (err) 65 + panic("Unable to fixup FDT: %d", err); 66 + 67 + return fdt_buf; 68 + 69 + } 70 + 71 + static const struct of_device_id realtek_of_match[] __initconst = { 72 + { .compatible = "realtek,rtl9302-soc" }, 73 + {} 74 + }; 75 + 76 + MIPS_MACHINE(realtek) = { 77 + .matches = realtek_of_match, 78 + .fixup_fdt = realtek_fixup_fdt, 79 + };