svn commit: r258798 - in head/sys: conf dev/uart

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Dec 1 16:02:23 UTC 2013


Author: nwhitehorn
Date: Sun Dec  1 16:02:22 2013
New Revision: 258798
URL: http://svnweb.freebsd.org/changeset/base/258798

Log:
  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.

Modified:
  head/sys/conf/files.powerpc
  head/sys/dev/uart/uart_cpu_powerpc.c

Modified: head/sys/conf/files.powerpc
==============================================================================
--- head/sys/conf/files.powerpc	Sun Dec  1 15:24:35 2013	(r258797)
+++ head/sys/conf/files.powerpc	Sun Dec  1 16:02:22 2013	(r258798)
@@ -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

Modified: head/sys/dev/uart/uart_cpu_powerpc.c
==============================================================================
--- head/sys/dev/uart/uart_cpu_powerpc.c	Sun Dec  1 15:24:35 2013	(r258797)
+++ head/sys/dev/uart/uart_cpu_powerpc.c	Sun Dec  1 16:02:22 2013	(r258798)
@@ -61,42 +61,96 @@ ofw_get_uart_console(phandle_t opts, pha
 	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
 		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
 	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);
 }
+


More information about the svn-src-head mailing list