diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/legacy_serial.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index d179ec502292..59164ba2eb1c 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -36,7 +36,8 @@ static int legacy_serial_console = -1; | |||
36 | 36 | ||
37 | static int __init add_legacy_port(struct device_node *np, int want_index, | 37 | static int __init add_legacy_port(struct device_node *np, int want_index, |
38 | int iotype, phys_addr_t base, | 38 | int iotype, phys_addr_t base, |
39 | phys_addr_t taddr, unsigned long irq) | 39 | phys_addr_t taddr, unsigned long irq, |
40 | unsigned int flags) | ||
40 | { | 41 | { |
41 | u32 *clk, *spd, clock = BASE_BAUD * 16; | 42 | u32 *clk, *spd, clock = BASE_BAUD * 16; |
42 | int index; | 43 | int index; |
@@ -90,7 +91,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
90 | legacy_serial_ports[index].iotype = iotype; | 91 | legacy_serial_ports[index].iotype = iotype; |
91 | legacy_serial_ports[index].uartclk = clock; | 92 | legacy_serial_ports[index].uartclk = clock; |
92 | legacy_serial_ports[index].irq = irq; | 93 | legacy_serial_ports[index].irq = irq; |
93 | legacy_serial_ports[index].flags = ASYNC_BOOT_AUTOCONF; | 94 | legacy_serial_ports[index].flags = flags; |
94 | legacy_serial_infos[index].taddr = taddr; | 95 | legacy_serial_infos[index].taddr = taddr; |
95 | legacy_serial_infos[index].np = of_node_get(np); | 96 | legacy_serial_infos[index].np = of_node_get(np); |
96 | legacy_serial_infos[index].clock = clock; | 97 | legacy_serial_infos[index].clock = clock; |
@@ -107,6 +108,32 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
107 | return index; | 108 | return index; |
108 | } | 109 | } |
109 | 110 | ||
111 | static int __init add_legacy_soc_port(struct device_node *np, | ||
112 | struct device_node *soc_dev) | ||
113 | { | ||
114 | phys_addr_t addr; | ||
115 | u32 *addrp; | ||
116 | unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; | ||
117 | |||
118 | /* We only support ports that have a clock frequency properly | ||
119 | * encoded in the device-tree. | ||
120 | */ | ||
121 | if (get_property(np, "clock-frequency", NULL) == NULL) | ||
122 | return -1; | ||
123 | |||
124 | /* Get the address */ | ||
125 | addrp = of_get_address(soc_dev, 0, NULL, NULL); | ||
126 | if (addrp == NULL) | ||
127 | return -1; | ||
128 | |||
129 | addr = of_translate_address(soc_dev, addrp); | ||
130 | |||
131 | /* Add port, irq will be dealt with later. We passed a translated | ||
132 | * IO port value. It will be fixed up later along with the irq | ||
133 | */ | ||
134 | return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); | ||
135 | } | ||
136 | |||
110 | static int __init add_legacy_isa_port(struct device_node *np, | 137 | static int __init add_legacy_isa_port(struct device_node *np, |
111 | struct device_node *isa_bridge) | 138 | struct device_node *isa_bridge) |
112 | { | 139 | { |
@@ -137,7 +164,7 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
137 | taddr = of_translate_address(np, reg); | 164 | taddr = of_translate_address(np, reg); |
138 | 165 | ||
139 | /* Add port, irq will be dealt with later */ | 166 | /* Add port, irq will be dealt with later */ |
140 | return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ); | 167 | return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); |
141 | 168 | ||
142 | } | 169 | } |
143 | 170 | ||
@@ -204,7 +231,7 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
204 | /* Add port, irq will be dealt with later. We passed a translated | 231 | /* Add port, irq will be dealt with later. We passed a translated |
205 | * IO port value. It will be fixed up later along with the irq | 232 | * IO port value. It will be fixed up later along with the irq |
206 | */ | 233 | */ |
207 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ); | 234 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF); |
208 | } | 235 | } |
209 | 236 | ||
210 | /* | 237 | /* |
@@ -218,7 +245,7 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
218 | */ | 245 | */ |
219 | void __init find_legacy_serial_ports(void) | 246 | void __init find_legacy_serial_ports(void) |
220 | { | 247 | { |
221 | struct device_node *np, *stdout; | 248 | struct device_node *np, *stdout = NULL; |
222 | char *path; | 249 | char *path; |
223 | int index; | 250 | int index; |
224 | 251 | ||
@@ -226,13 +253,23 @@ void __init find_legacy_serial_ports(void) | |||
226 | 253 | ||
227 | /* Now find out if one of these is out firmware console */ | 254 | /* Now find out if one of these is out firmware console */ |
228 | path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); | 255 | path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); |
229 | if (path == NULL) { | 256 | if (path != NULL) { |
257 | stdout = of_find_node_by_path(path); | ||
258 | if (stdout) | ||
259 | DBG("stdout is %s\n", stdout->full_name); | ||
260 | } else { | ||
230 | DBG(" no linux,stdout-path !\n"); | 261 | DBG(" no linux,stdout-path !\n"); |
231 | return; | ||
232 | } | 262 | } |
233 | stdout = of_find_node_by_path(path); | 263 | |
234 | if (stdout) { | 264 | /* First fill our array with SOC ports */ |
235 | DBG("stdout is %s\n", stdout->full_name); | 265 | for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { |
266 | struct device_node *soc = of_get_parent(np); | ||
267 | if (soc && !strcmp(soc->type, "soc")) { | ||
268 | index = add_legacy_soc_port(np, np); | ||
269 | if (index >= 0 && np == stdout) | ||
270 | legacy_serial_console = index; | ||
271 | } | ||
272 | of_node_put(soc); | ||
236 | } | 273 | } |
237 | 274 | ||
238 | /* First fill our array with ISA ports */ | 275 | /* First fill our array with ISA ports */ |
@@ -437,6 +474,11 @@ static int __init check_legacy_serial_console(void) | |||
437 | DBG(" of_chosen is NULL !\n"); | 474 | DBG(" of_chosen is NULL !\n"); |
438 | return -ENODEV; | 475 | return -ENODEV; |
439 | } | 476 | } |
477 | |||
478 | if (legacy_serial_console < 0) { | ||
479 | DBG(" legacy_serial_console not found !\n"); | ||
480 | return -ENODEV; | ||
481 | } | ||
440 | /* We are getting a weird phandle from OF ... */ | 482 | /* We are getting a weird phandle from OF ... */ |
441 | /* ... So use the full path instead */ | 483 | /* ... So use the full path instead */ |
442 | name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); | 484 | name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); |