Make uart_cpu_powerpc work on both FDT and OFW systems. This is the last
remaining modification required to build kernels that work with both on PowerPC.
This commit is contained in:
parent
46b13263cf
commit
49aba28afe
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258798
@ -63,8 +63,7 @@ dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/tsec/if_tsec.c optional tsec
|
||||
dev/tsec/if_tsec_fdt.c optional tsec fdt
|
||||
dev/uart/uart_cpu_fdt.c optional uart fdt
|
||||
dev/uart/uart_cpu_powerpc.c optional uart aim
|
||||
dev/uart/uart_cpu_powerpc.c optional uart
|
||||
dev/usb/controller/ehci_fsl.c optional ehci mpc85xx
|
||||
kern/kern_clocksource.c standard
|
||||
kern/subr_dummy_vdso_tc.c standard
|
||||
|
@ -61,42 +61,96 @@ ofw_get_uart_console(phandle_t opts, phandle_t *result, const char *inputdev,
|
||||
input = OF_finddevice(buf);
|
||||
if (input == -1)
|
||||
return (ENXIO);
|
||||
if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
|
||||
return (ENXIO);
|
||||
if (OF_finddevice(buf) != input)
|
||||
return (ENXIO);
|
||||
|
||||
if (outputdev != NULL) {
|
||||
if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
|
||||
return (ENXIO);
|
||||
if (OF_finddevice(buf) != input)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
*result = input;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
|
||||
const char *prop)
|
||||
{
|
||||
union {
|
||||
char buf[64];
|
||||
phandle_t ref;
|
||||
} field;
|
||||
phandle_t output;
|
||||
ssize_t size;
|
||||
|
||||
size = OF_getproplen(node, prop);
|
||||
if (size == -1)
|
||||
return (ENXIO);
|
||||
OF_getprop(node, prop, &field, sizeof(field));
|
||||
|
||||
/* This property might be a phandle or might be a path. Hooray. */
|
||||
|
||||
output = -1;
|
||||
if (field.buf[size - 1] == 0)
|
||||
output = OF_finddevice(field.buf);
|
||||
if (output == -1 && size == 4)
|
||||
output = OF_xref_phandle(field.ref);
|
||||
|
||||
if (output != -1) {
|
||||
*result = output;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
int
|
||||
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
{
|
||||
char buf[64];
|
||||
struct uart_class *class;
|
||||
phandle_t input, opts;
|
||||
phandle_t input, opts, chosen;
|
||||
int error;
|
||||
|
||||
class = &uart_z8530_class;
|
||||
if (class == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
if ((opts = OF_finddevice("/options")) == -1)
|
||||
return (ENXIO);
|
||||
opts = OF_finddevice("/options");
|
||||
chosen = OF_finddevice("/chosen");
|
||||
switch (devtype) {
|
||||
case UART_DEV_CONSOLE:
|
||||
if (ofw_get_uart_console(opts, &input, "input-device",
|
||||
"output-device")) {
|
||||
/*
|
||||
* At least some G5 Xserves require that we
|
||||
* probe input-device-1 as well
|
||||
*/
|
||||
|
||||
if (ofw_get_uart_console(opts, &input, "input-device-1",
|
||||
"output-device-1"))
|
||||
return (ENXIO);
|
||||
error = ENXIO;
|
||||
if (chosen != -1 && error != 0)
|
||||
error = ofw_get_uart_console(chosen, &input,
|
||||
"stdout-path", NULL);
|
||||
if (chosen != -1 && error != 0)
|
||||
error = ofw_get_uart_console(chosen, &input,
|
||||
"linux,stdout-path", NULL);
|
||||
if (chosen != -1 && error != 0)
|
||||
error = ofw_get_console_phandle_path(chosen, &input,
|
||||
"stdout");
|
||||
if (chosen != -1 && error != 0)
|
||||
error = ofw_get_uart_console(chosen, &input,
|
||||
"stdin-path", NULL);
|
||||
if (chosen != -1 && error != 0)
|
||||
error = ofw_get_console_phandle_path(chosen, &input,
|
||||
"stdin");
|
||||
if (opts != -1 && error != 0)
|
||||
error = ofw_get_uart_console(opts, &input,
|
||||
"input-device", "output-device");
|
||||
if (opts != -1 && error != 0)
|
||||
error = ofw_get_uart_console(opts, &input,
|
||||
"input-device-1", "output-device-1");
|
||||
if (error != 0) {
|
||||
input = OF_finddevice("serial0"); /* Last ditch */
|
||||
if (input == -1)
|
||||
error = (ENXIO);
|
||||
}
|
||||
|
||||
if (error != 0)
|
||||
return (error);
|
||||
break;
|
||||
case UART_DEV_DBGPORT:
|
||||
if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf)))
|
||||
@ -113,14 +167,14 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
return (ENXIO);
|
||||
if (strcmp(buf, "serial") != 0)
|
||||
return (ENXIO);
|
||||
if (OF_getprop(input, "name", buf, sizeof(buf)) == -1)
|
||||
if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if (strcmp(buf, "ch-a") == 0) {
|
||||
if (strncmp(buf, "chrp,es", 7) == 0) {
|
||||
class = &uart_z8530_class;
|
||||
di->bas.regshft = 4;
|
||||
di->bas.chan = 1;
|
||||
} else if (strcmp(buf,"serial") == 0) {
|
||||
} else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
|
||||
class = &uart_ns8250_class;
|
||||
di->bas.regshft = 0;
|
||||
di->bas.chan = 0;
|
||||
@ -139,9 +193,12 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
if (OF_getprop(input, "current-speed", &di->baudrate,
|
||||
sizeof(di->baudrate)) == -1)
|
||||
di->baudrate = 0;
|
||||
OF_getprop(input, "reg-shift", &di->bas.regshft,
|
||||
sizeof(di->bas.regshft));
|
||||
|
||||
di->databits = 8;
|
||||
di->stopbits = 1;
|
||||
di->parity = UART_PARITY_NONE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user