aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-23 01:56:06 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:49:50 -0500
commit463ce0e103f419f51b1769111e73fe8bb305d0ec (patch)
treeb4ffced87b886d81b518790fcaf841dd006e8068 /arch/powerpc/platforms/pseries
parentd1405b869850982f05c7ec0d3f137ca27588192f (diff)
[PATCH] powerpc: serial port discovery (#2)
This moves the discovery of legacy serial ports to a separate file, makes it common to ppc32 and ppc64, and reworks it to use the new OF address translators to get to the ports early. This new version can also detect some PCI serial cards using legacy chips and will probably match those discovered port with the default console choice. Only ppc64 gets udbg still yet, unifying udbg isn't finished yet. It also adds some speed-probing code to udbg so that the default console can come up at the same speed it was set to by the firmware. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c68
-rw-r--r--arch/powerpc/platforms/pseries/setup.c14
2 files changed, 30 insertions, 52 deletions
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index cf1bc11b3346..cc0939d4cad1 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -24,6 +24,7 @@
24#include <linux/config.h> 24#include <linux/config.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/console.h>
27#include <asm/processor.h> 28#include <asm/processor.h>
28#include <asm/mmu.h> 29#include <asm/mmu.h>
29#include <asm/page.h> 30#include <asm/page.h>
@@ -191,7 +192,7 @@ static unsigned char udbg_getcLP(void)
191/* call this from early_init() for a working debug console on 192/* call this from early_init() for a working debug console on
192 * vterm capable LPAR machines 193 * vterm capable LPAR machines
193 */ 194 */
194void udbg_init_debug_lpar(void) 195void __init udbg_init_debug_lpar(void)
195{ 196{
196 vtermno = 0; 197 vtermno = 0;
197 udbg_putc = udbg_putcLP; 198 udbg_putc = udbg_putcLP;
@@ -200,63 +201,54 @@ void udbg_init_debug_lpar(void)
200} 201}
201 202
202/* returns 0 if couldn't find or use /chosen/stdout as console */ 203/* returns 0 if couldn't find or use /chosen/stdout as console */
203int find_udbg_vterm(void) 204void __init find_udbg_vterm(void)
204{ 205{
205 struct device_node *stdout_node; 206 struct device_node *stdout_node;
206 u32 *termno; 207 u32 *termno;
207 char *name; 208 char *name;
208 int found = 0; 209 int add_console;
209 210
210 /* find the boot console from /chosen/stdout */ 211 /* find the boot console from /chosen/stdout */
211 if (!of_chosen) 212 if (!of_chosen)
212 return 0; 213 return;
213 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
214 if (name == NULL) 215 if (name == NULL)
215 return 0; 216 return;
216 stdout_node = of_find_node_by_path(name); 217 stdout_node = of_find_node_by_path(name);
217 if (!stdout_node) 218 if (!stdout_node)
218 return 0; 219 return;
219
220 /* now we have the stdout node; figure out what type of device it is. */
221 name = (char *)get_property(stdout_node, "name", NULL); 220 name = (char *)get_property(stdout_node, "name", NULL);
222 if (!name) { 221 if (!name) {
223 printk(KERN_WARNING "stdout node missing 'name' property!\n"); 222 printk(KERN_WARNING "stdout node missing 'name' property!\n");
224 goto out; 223 goto out;
225 } 224 }
225 /* The user has requested a console so this is already set up. */
226 add_console = !strstr(cmd_line, "console=");
226 227
227 if (strncmp(name, "vty", 3) == 0) { 228 /* Check if it's a virtual terminal */
228 if (device_is_compatible(stdout_node, "hvterm1")) { 229 if (strncmp(name, "vty", 3) != 0)
229 termno = (u32 *)get_property(stdout_node, "reg", NULL); 230 goto out;
230 if (termno) { 231 termno = (u32 *)get_property(stdout_node, "reg", NULL);
231 vtermno = termno[0]; 232 if (termno == NULL)
232 udbg_putc = udbg_putcLP; 233 goto out;
233 udbg_getc = udbg_getcLP; 234 vtermno = termno[0];
234 udbg_getc_poll = udbg_getc_pollLP; 235
235 found = 1; 236 if (device_is_compatible(stdout_node, "hvterm1")) {
236 } 237 udbg_putc = udbg_putcLP;
237 } else if (device_is_compatible(stdout_node, "hvterm-protocol")) { 238 udbg_getc = udbg_getcLP;
238 termno = (u32 *)get_property(stdout_node, "reg", NULL); 239 udbg_getc_poll = udbg_getc_pollLP;
239 if (termno) { 240 if (add_console)
240 vtermno = termno[0]; 241 add_preferred_console("hvc", termno[0] & 0xff, NULL);
241 udbg_putc = udbg_hvsi_putc; 242 } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
242 udbg_getc = udbg_hvsi_getc; 243 vtermno = termno[0];
243 udbg_getc_poll = udbg_hvsi_getc_poll; 244 udbg_putc = udbg_hvsi_putc;
244 found = 1; 245 udbg_getc = udbg_hvsi_getc;
245 } 246 udbg_getc_poll = udbg_hvsi_getc_poll;
246 } 247 if (add_console)
247 } else if (strncmp(name, "serial", 6)) { 248 add_preferred_console("hvsi", termno[0] & 0xff, NULL);
248 /* XXX fix ISA serial console */
249 printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
250 "can't print udbg messages\n",
251 stdout_node->full_name);
252 } else {
253 printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
254 stdout_node->full_name);
255 } 249 }
256
257out: 250out:
258 of_node_put(stdout_node); 251 of_node_put(stdout_node);
259 return found;
260} 252}
261 253
262void vpa_init(int cpu) 254void vpa_init(int cpu)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8a4238a3757f..8828dc378c3e 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -79,8 +79,6 @@
79extern void find_udbg_vterm(void); 79extern void find_udbg_vterm(void);
80extern void system_reset_fwnmi(void); /* from head.S */ 80extern void system_reset_fwnmi(void); /* from head.S */
81extern void machine_check_fwnmi(void); /* from head.S */ 81extern void machine_check_fwnmi(void); /* from head.S */
82extern void generic_find_legacy_serial_ports(u64 *physport,
83 unsigned int *default_speed);
84 82
85int fwnmi_active; /* TRUE if an FWNMI handler is present */ 83int fwnmi_active; /* TRUE if an FWNMI handler is present */
86 84
@@ -366,10 +364,7 @@ static int pseries_set_xdabr(unsigned long dabr)
366 */ 364 */
367static void __init pSeries_init_early(void) 365static void __init pSeries_init_early(void)
368{ 366{
369 void *comport;
370 int iommu_off = 0; 367 int iommu_off = 0;
371 unsigned int default_speed;
372 u64 physport;
373 368
374 DBG(" -> pSeries_init_early()\n"); 369 DBG(" -> pSeries_init_early()\n");
375 370
@@ -383,17 +378,8 @@ static void __init pSeries_init_early(void)
383 get_property(of_chosen, "linux,iommu-off", NULL)); 378 get_property(of_chosen, "linux,iommu-off", NULL));
384 } 379 }
385 380
386 generic_find_legacy_serial_ports(&physport, &default_speed);
387
388 if (platform_is_lpar()) 381 if (platform_is_lpar())
389 find_udbg_vterm(); 382 find_udbg_vterm();
390 else if (physport) {
391 /* Map the uart for udbg. */
392 comport = (void *)ioremap(physport, 16);
393 udbg_init_uart(comport, default_speed);
394
395 DBG("Hello World !\n");
396 }
397 383
398 if (firmware_has_feature(FW_FEATURE_DABR)) 384 if (firmware_has_feature(FW_FEATURE_DABR))
399 ppc_md.set_dabr = pseries_set_dabr; 385 ppc_md.set_dabr = pseries_set_dabr;