Commit 6a4f4509 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: vty updates, from Hollis Blanchard

From: Anton Blanchard <anton@samba.org>

vty updates, from Hollis Blanchard
parent 40399e6d
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/hvcall.h> #include <asm/hvcall.h>
#include <asm/prom.h>
long plpar_pte_remove(unsigned long flags, long plpar_pte_remove(unsigned long flags,
unsigned long ptex, unsigned long ptex,
...@@ -206,6 +207,63 @@ static unsigned char udbg_getcLP(void) ...@@ -206,6 +207,63 @@ static unsigned char udbg_getcLP(void)
} }
} }
/* returns 0 if couldn't find or use /chosen/stdout as console */
static int find_udbg_vterm(void)
{
struct device_node *stdout_node;
u32 *termno;
char *name;
int found = 0;
/* find the boot console from /chosen/stdout */
if (!of_stdout_device) {
printk(KERN_WARNING "couldn't get path from /chosen/stdout!\n");
return found;
}
stdout_node = of_find_node_by_path(of_stdout_device);
if (!stdout_node) {
printk(KERN_WARNING "couldn't find node from /chosen/stdout\n");
return found;
}
/* now we have the stdout node; figure out what type of device it is. */
name = (char *)get_property(stdout_node, "name", 0);
if (!name) {
printk(KERN_WARNING "stdout node missing 'name' property!\n");
goto out;
}
if (strncmp(name, "vty", 3) == 0) {
char *compatible;
compatible = (char *)get_property(stdout_node, "compatible", 0);
if (compatible && (strncmp(compatible, "hvterm1", 7) == 0)) {
termno = (u32 *)get_property(stdout_node, "reg", 0);
if (termno) {
vtermno = termno[0];
ppc_md.udbg_putc = udbg_putcLP;
ppc_md.udbg_getc = udbg_getcLP;
ppc_md.udbg_getc_poll = udbg_getc_pollLP;
found = 1;
}
} else {
/* XXX implement udbg_putcLP_vtty for hvterm-protocol1 case */
printk(KERN_WARNING "%s doesn't speak hvterm1; "
"can't print udbg messages\n", of_stdout_device);
}
} else if (strncmp(name, "serial", 6)) {
/* XXX fix ISA serial console */
printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
"can't print udbg messages\n", of_stdout_device);
} else {
printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
of_stdout_device);
}
out:
of_node_put(stdout_node);
return found;
}
void pSeries_lpar_mm_init(void); void pSeries_lpar_mm_init(void);
/* This is called early in setup.c. /* This is called early in setup.c.
...@@ -213,8 +271,6 @@ void pSeries_lpar_mm_init(void); ...@@ -213,8 +271,6 @@ void pSeries_lpar_mm_init(void);
*/ */
void pSeriesLP_init_early(void) void pSeriesLP_init_early(void)
{ {
struct device_node *np;
pSeries_lpar_mm_init(); pSeries_lpar_mm_init();
ppc_md.tce_build = tce_build_pSeriesLP; ppc_md.tce_build = tce_build_pSeriesLP;
...@@ -225,25 +281,13 @@ void pSeriesLP_init_early(void) ...@@ -225,25 +281,13 @@ void pSeriesLP_init_early(void)
#endif #endif
/* The keyboard is not useful in the LPAR environment. /* The keyboard is not useful in the LPAR environment.
* Leave all the interfaces NULL. * Leave all the ppc_md keyboard interfaces NULL.
*/ */
/* lookup the first virtual terminal number in case we don't have a if (0 == find_udbg_vterm()) {
* com port. Zero is probably correct in case someone calls udbg printk(KERN_WARNING
* before the init. The property is a pair of numbers. The first "can't use stdout; can't print early debug messages.\n");
* is the starting termno (the one we use) and the second is the
* number of terminals.
*/
np = of_find_node_by_path("/rtas");
if (np) {
u32 *termno = (u32 *)get_property(np, "ibm,termno", 0);
if (termno)
vtermno = termno[0];
of_node_put(np);
} }
ppc_md.udbg_putc = udbg_putcLP;
ppc_md.udbg_getc = udbg_getcLP;
ppc_md.udbg_getc_poll = udbg_getc_pollLP;
} }
int hvc_get_chars(int index, char *buf, int count) int hvc_get_chars(int index, char *buf, int count)
...@@ -286,25 +330,28 @@ int hvc_put_chars(int index, const char *buf, int count) ...@@ -286,25 +330,28 @@ int hvc_put_chars(int index, const char *buf, int count)
return -1; return -1;
} }
/* return the number of client vterms present */
/* XXX this requires an interface change to handle multiple discontiguous
* vterms */
int hvc_count(int *start_termno) int hvc_count(int *start_termno)
{ {
u32 *termno; u32 *termno;
struct device_node *dn; struct device_node *vty;
int ret = 0;
/* consider only the first vty node.
if ((dn = of_find_node_by_path("/rtas")) != NULL) { * we should _always_ be able to find one. */
if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) { vty = of_find_node_by_name(NULL, "vty");
if (start_termno) if (vty) {
*start_termno = termno[0]; if ((termno = (u32 *)get_property(vty, "reg", 0)) != NULL) {
ret = termno[1]; *start_termno = *termno;
} }
of_node_put(dn); of_node_put(vty);
return 1; /* we can't support >1 with this interface */
} }
return ret;
}
/* couldn't find any vterms */
return 0;
}
long pSeries_lpar_hpte_insert(unsigned long hpte_group, long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long prpn, unsigned long va, unsigned long prpn,
......
...@@ -127,8 +127,10 @@ udbg_write(const char *s, int n) ...@@ -127,8 +127,10 @@ udbg_write(const char *s, int n)
{ {
int remain = n; int remain = n;
char c; char c;
if (!ppc_md.udbg_putc) if (!ppc_md.udbg_putc)
for (;;); /* stop here for cpuctl */ return 0;
if ( s && *s != '\0' ) { if ( s && *s != '\0' ) {
while ( (( c = *s++ ) != '\0') && (remain-- > 0)) { while ( (( c = *s++ ) != '\0') && (remain-- > 0)) {
ppc_md.udbg_putc(c); ppc_md.udbg_putc(c);
......
...@@ -169,6 +169,7 @@ struct prom_t { ...@@ -169,6 +169,7 @@ struct prom_t {
}; };
extern struct prom_t prom; extern struct prom_t prom;
extern char *of_stdout_device;
extern int boot_cpuid; extern int boot_cpuid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment