Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Feb 2010 17:34:10 GMT
From:      Rafal Jaworowski <raj@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 174730 for review
Message-ID:  <201002151734.o1FHYA7w059552@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=174730

Change 174730 by raj@raj_fdt on 2010/02/15 17:33:44

	Consolidate FDT attachment of uart(4) driver.
	
	- Move all FDT-related routines into one file.
	- Collapse duplicate code to shared helper routines.
	- Teach the attachment to be endian-safe.
	- Make Marvell ARM use the FDT-base console code (remove the file used
	  so far altogether).

Affected files ...

.. //depot/projects/fdt/sys/arm/mv/files.mv#4 edit
.. //depot/projects/fdt/sys/conf/files.powerpc#17 edit
.. //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#6 edit
.. //depot/projects/fdt/sys/dev/uart/uart_cpu_mv.c#2 delete
.. //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#6 edit

Differences ...

==== //depot/projects/fdt/sys/arm/mv/files.mv#4 (text+ko) ====

@@ -29,6 +29,5 @@
 arm/mv/twsi.c			optional	iicbus
 
 dev/mge/if_mge.c		optional	mge
-dev/uart/uart_cpu_mv.c		optional	uart
 dev/uart/uart_dev_ns8250.c	optional	uart
 dev/usb/controller/ehci_mv.c	optional	ehci

==== //depot/projects/fdt/sys/conf/files.powerpc#17 (text+ko) ====

@@ -61,7 +61,7 @@
 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_powerpc.c	optional	uart
+dev/uart/uart_cpu_powerpc.c	optional	uart aim
 kern/syscalls.c			optional	ktr
 libkern/ashldi3.c		standard
 libkern/ashrdi3.c		standard

==== //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#6 (text+ko) ====

@@ -36,13 +36,14 @@
 #include <sys/module.h>
 
 #include <machine/bus.h>
+#include <machine/fdt.h>
 
+#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_bus.h>
-
-#include "../../contrib/dtc/libfdt/libfdt_env.h"
+#include <dev/uart/uart_cpu.h>
 
 static int uart_fdt_probe(device_t);
 
@@ -61,19 +62,10 @@
 };
 
 static int
-uart_fdt_probe(device_t dev)
+uart_fdt_get_clock(phandle_t node, pcell_t *cell)
 {
-	struct uart_softc *sc;
-	phandle_t node;
-	pcell_t clock, shift;
-
-	if (!ofw_bus_is_compatible(dev, "ns16550"))
-		return (ENXIO);
-
-	sc = device_get_softc(dev);
-	sc->sc_class = &uart_ns8250_class;
+	pcell_t clock;
 
-	node = ofw_bus_get_node(dev);
 	if ((OF_getprop(node, "clock-frequency", &clock,
 	    sizeof(clock))) <= 0)
 		return (ENXIO);
@@ -85,13 +77,124 @@
 		    sizeof(clock))) <= 0)
 			clock = 0;
 
-	clock = fdt32_to_cpu(clock);
+	*cell = fdt32_to_cpu(clock);
+	return (0);
+}
+
+static int
+uart_fdt_get_shift(phandle_t node, pcell_t *cell)
+{
+	pcell_t shift;
 
 	if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0)
 		shift = 0;
-	shift = fdt32_to_cpu(shift);
+	*cell = fdt32_to_cpu(shift);
+	return (0);
+}
+
+static int
+uart_fdt_probe(device_t dev)
+{
+	struct uart_softc *sc;
+	phandle_t node;
+	pcell_t clock, shift;
+	int err;
+
+	if (!ofw_bus_is_compatible(dev, "ns16550"))
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+
+	node = ofw_bus_get_node(dev);
+
+	if ((err = uart_fdt_get_clock(node, &clock)) != 0)
+		return (err);
+	uart_fdt_get_shift(node, &shift);
 
 	return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
 }
 
 DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0);
+
+/*
+ * UART console routines.
+ */
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+
+	return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+	char buf[64];
+	struct uart_class *class;
+	phandle_t node, chosen;
+	pcell_t shift, br, rclk;
+	u_long start, size;
+	int err;
+
+	if (devtype != UART_DEV_CONSOLE)
+		return (ENXIO);
+
+	/*
+	 * Retrieve /chosen/std{in,out}.
+	 */
+	if ((chosen = OF_finddevice("/chosen")) == 0)
+		return (ENXIO);
+	if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0)
+		return (ENXIO);
+	if ((node = OF_finddevice(buf)) == 0)
+		return (ENXIO);
+	if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0)
+		return (ENXIO);
+	if (OF_finddevice(buf) != node)
+		/* Only stdin == stdout is supported. */
+		return (ENXIO);
+	/*
+	 * Retrieve serial attributes.
+	 */
+	uart_fdt_get_shift(node, &shift);
+
+	if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
+		br = 0;
+	br = fdt32_to_cpu(br);
+
+	if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
+		return (err);
+	/*
+	 * Finalize configuration.
+	 */
+	class = &uart_quicc_class;
+	if (fdt_is_compatible(node, "ns16550"))
+		class = &uart_ns8250_class;
+
+	di->bas.chan = 0;
+	di->bas.regshft = (u_int)shift;
+	di->baudrate = 0;
+	di->bas.rclk = (u_int)rclk;
+	di->ops = uart_getops(class);
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	di->bas.bst = fdtbus_bs_tag;
+
+	err = fdt_get_regsize(node, &start, &size);
+	if (err)
+		return (ENXIO);
+	start += FDT_IMMR_VA;
+
+	uart_bus_space_mem = fdtbus_bs_tag;
+	uart_bus_space_io = NULL;
+
+	if (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh) != 0)
+		return (ENXIO);
+
+	return (0);
+}

==== //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#6 (text) ====

@@ -27,47 +27,26 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/sys/dev/uart/uart_cpu_powerpc.c,v 1.8 2009/07/23 12:51:27 nwhitehorn Exp $");
 
-#include "opt_platform.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
 #include <machine/bus.h>
-
-#ifdef FDT
-#include <sys/bus.h>
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/ofw_bus.h>
-#include <machine/fdt.h>
-#endif
+#include <machine/ofw_machdep.h>
 
 #include <dev/ofw/openfirm.h>
-
-#ifndef FDT
-#include <machine/ofw_machdep.h>
-#endif
-
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_cpu.h>
 
-#ifdef FDT
-bus_space_tag_t uart_bus_space_io = fdtbus_bs_tag;
-bus_space_tag_t uart_bus_space_mem = fdtbus_bs_tag;
-#else
 bus_space_tag_t uart_bus_space_io = &bs_le_tag;
 bus_space_tag_t uart_bus_space_mem = &bs_le_tag;
-#endif
 
 int
 uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
 {
-#ifdef FDT
-	return ((b1->bsh == b2->bsh) ? 1 : 0);
-#else
+
 	return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0);
-#endif
 }
 
 static int
@@ -91,105 +70,6 @@
 	return (0);
 }
 
-#ifdef FDT
-static int
-fdt_uart_addr(phandle_t node, bus_space_tag_t *tag, bus_space_handle_t *handle)
-{
-	pcell_t prop[4];
-	u_long start, size;
-	pcell_t par_addr_cells, par_size_cells;
-	int rv, tuples, tuple_size;
-	ssize_t len;
-
-	if (node == 0)
-		return (EINVAL);
-	if (tag == NULL || handle == NULL)
-		return (EINVAL);
-	if ((len = OF_getproplen(node, "reg")) <= 0)
-		return (EINVAL);
-	if (len > sizeof(prop))
-		return (ERANGE);
-
-	par_addr_cells = fdt_parent_addr_cells(node);
-	if (par_addr_cells > 0) {
-		rv = OF_searchprop(OF_parent(node), "#size-cells",
-		    &par_size_cells, sizeof(par_size_cells));
-		if (rv <= 0)
-			par_size_cells = 1;
-	} else
-		par_size_cells = 0;
-
-	tuple_size = sizeof(pcell_t) * (par_addr_cells + par_size_cells);
-	len = OF_getprop(node, "reg", prop, sizeof(prop));
-	if (len % tuple_size)
-		return (ENXIO);
-
-	tuples = len / tuple_size;
-	if (tuples <= 0)
-		return (ENXIO);
-
-	start = size = 0;
-	rv = 0;
-	*tag = uart_bus_space_io;
-
-	/*
-	 * Get address/size. XXX we assume only first 'reg' tuple is used:
-	 * uart nodes usually have only one, so this will break if the range
-	 * to be used is specified in other tuples.
-	 */
-	rv = fdt_data_to_res(prop, par_addr_cells, par_size_cells,
-	    &start, &size);
-
-	start += FDT_IMMR_VA;
-
-	rv = bus_space_map(*tag, start, size, 0, handle);
-	if (rv)
-		return (ERANGE);
-
-	return (0);
-}
-
-int
-uart_cpu_getdev(int devtype, struct uart_devinfo *di)
-{
-	struct uart_class *class;
-	phandle_t input, opts;
-	int error;
-
-	if (devtype != UART_DEV_CONSOLE)
-		return (ENXIO);
-
-	if ((opts = OF_finddevice("/chosen")) == 0)
-		return (ENXIO);
-
-	if (ofw_get_uart_console(opts, &input, "stdin", "stdout"))
-		return (EINVAL);
-
-	class = &uart_quicc_class;
-	if (fdt_is_compatible(input, "ns16550"))
-		class = &uart_ns8250_class;
-
-	if (OF_getprop(input, "reg-shift", &di->bas.regshft,
-	    di->bas.regshft) <= 0)
-		di->bas.regshft = 0;
-
-	di->ops = uart_getops(class);
-
-	if (OF_getprop(input, "current-speed", &di->baudrate,
-	    sizeof(di->baudrate)) <= 0)
-		di->baudrate = 0;
-
-	di->databits = 8;
-	di->stopbits = 1;
-	di->parity = UART_PARITY_NONE;
-
-	error = fdt_uart_addr(input, &di->bas.bst, &di->bas.bsh);
-	if (error)
-		return (error);
-
-	return (0);
-}
-#else
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
@@ -265,4 +145,3 @@
 	di->parity = UART_PARITY_NONE;
 	return (0);
 }
-#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002151734.o1FHYA7w059552>