Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Procedures for creating, accessing and interpreting the device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Paul Mackerras	August 1996.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 1996-2005 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *    {engebret|bergner}@us.ibm.com 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  Adapted for sparc32 by David S. Miller davem@davemloft.net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/oplib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/leon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/leon_amba.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "prom.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) void * __init prom_early_alloc(unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	ret = memblock_alloc(size, SMP_CACHE_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		panic("%s: Failed to allocate %lu bytes\n", __func__, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	prom_early_allocated += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* The following routines deal with the black magic of fully naming a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * Certain well known named nodes are just the simple name string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * Actual devices have an address specifier appended to the base name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * string, like this "foo@addr".  The "addr" can be in any number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * formats, and the platform plus the type of the node determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * format and how it is constructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * For children of the ROOT node, the naming convention is fixed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * determined by whether this is a sun4u or sun4v system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * For children of other nodes, it is bus type specific.  So
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * we walk up the tree until we discover a "device_type" property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * we recognize and we go from there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct linux_prom_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct property *rprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	rprop = of_find_property(dp, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (!rprop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	regs = rprop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	sprintf(tmp_buf, "%s@%x,%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		regs->which_io, regs->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /* "name@slot,offset"  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct linux_prom_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	prop = of_find_property(dp, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	regs = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	sprintf(tmp_buf, "%s@%x,%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		regs->which_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		regs->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /* "name@devnum[,func]" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct linux_prom_pci_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	prop = of_find_property(dp, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	regs = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	devfn = (regs->phys_hi >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (devfn & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		sprintf(tmp_buf, "%s@%x,%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			devfn >> 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			devfn & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		sprintf(tmp_buf, "%s@%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			devfn >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* "name@addrhi,addrlo" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct linux_prom_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	prop = of_find_property(dp, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	regs = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	sprintf(tmp_buf, "%s@%x,%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		regs->which_io, regs->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* "name@irq,addrlo" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct amba_prom_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	unsigned int *intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	unsigned int reg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int interrupt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* In order to get a unique ID in the device tree (multiple AMBA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 * may have the same name) the node number is printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	prop = of_find_property(dp, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		reg0 = (unsigned int)dp->phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		regs = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		reg0 = regs->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	/* Not all cores have Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	prop = of_find_property(dp, "interrupts", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		intr = &interrupt; /* IRQ0 does not exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		intr = prop->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	sprintf(tmp_buf, "%s@%x,%x", name, *intr, reg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct device_node *parent = dp->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (parent != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		if (of_node_is_type(parent, "pci") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		    of_node_is_type(parent, "pciex"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			return pci_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (of_node_is_type(parent, "sbus"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			return sbus_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		if (of_node_is_type(parent, "ebus"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			return ebus_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		if (of_node_is_type(parent, "ambapp"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			return ambapp_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		/* "isa" is handled with platform naming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	/* Use platform naming convention.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	return sparc32_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) char * __init build_path_component(struct device_node *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	const char *name = of_get_property(dp, "name", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	char tmp_buf[64], *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	tmp_buf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	__build_path_component(dp, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if (tmp_buf[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		strcpy(tmp_buf, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	n = prom_early_alloc(strlen(tmp_buf) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	strcpy(n, tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) extern void restore_current(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void __init of_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	char *msg = "OF stdout device is: %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	struct device_node *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	phandle node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	int skip, tmp, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	of_console_path = prom_early_alloc(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	switch (prom_vers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	case PROM_V0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		switch (*romvec->pv_stdout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		case PROMDEV_SCREEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			type = "display";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		case PROMDEV_TTYB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		case PROMDEV_TTYA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			type = "serial";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			prom_printf("Invalid PROM_V0 stdout value %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 				    *romvec->pv_stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		tmp = skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		for_each_node_by_type(dp, type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			if (!tmp--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			prom_printf("Cannot find PROM_V0 console node.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		of_console_device = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		sprintf(of_console_path, "%pOF", dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		if (!strcmp(type, "serial")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			strcat(of_console_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			       (skip ? ":b" : ":a"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	case PROM_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	case PROM_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		fd = *romvec->pv_v2bootargs.fd_stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		spin_lock_irqsave(&prom_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		node = (*romvec->pv_v2devops.v2_inst2pkg)(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		restore_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		spin_unlock_irqrestore(&prom_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			prom_printf("Cannot resolve stdout node from "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				    "instance %08x.\n", fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		dp = of_find_node_by_phandle(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		if (!of_node_is_type(dp, "display") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		    !of_node_is_type(dp, "serial")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			prom_printf("Console device_type is neither display "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				    "nor serial.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		of_console_device = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		if (prom_vers == PROM_V2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			sprintf(of_console_path, "%pOF", dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			switch (*romvec->pv_stdout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			case PROMDEV_TTYA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				strcat(of_console_path, ":a");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			case PROMDEV_TTYB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 				strcat(of_console_path, ":b");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			const char *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			dp = of_find_node_by_path("/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			path = of_get_property(dp, "stdout-path", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			if (!path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				prom_printf("No stdout-path in root node.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 				prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			strcpy(of_console_path, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	of_console_options = strrchr(of_console_path, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (of_console_options) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		of_console_options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		if (*of_console_options == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			of_console_options = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	printk(msg, of_console_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) void __init of_fill_in_cpu_data(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) void __init irq_trans_init(struct device_node *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }