svn commit: r331885 - stable/11/sys/dev/uart
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Mon Apr 2 20:47:57 UTC 2018
Author: gonzo
Date: Mon Apr 2 20:47:55 2018
New Revision: 331885
URL: https://svnweb.freebsd.org/changeset/base/331885
Log:
MFC r303100 by andrew:
We will be switching to a new arm64 uart cpu driver that handles both FDT
and ACPI. As such pull out what will be the common parts of the FDT cpu
detection to a new function that can be shared between them.
Reviewed by: manu
Obtained from: ABT Systems Ltd
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D7262
Modified:
stable/11/sys/dev/uart/uart_bus_fdt.c
stable/11/sys/dev/uart/uart_cpu_fdt.c
stable/11/sys/dev/uart/uart_cpu_fdt.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/uart/uart_bus_fdt.c
==============================================================================
--- stable/11/sys/dev/uart/uart_bus_fdt.c Mon Apr 2 20:12:25 2018 (r331884)
+++ stable/11/sys/dev/uart/uart_bus_fdt.c Mon Apr 2 20:47:55 2018 (r331885)
@@ -105,6 +105,129 @@ uart_fdt_find_device(device_t dev)
}
static int
+phandle_chosen_propdev(phandle_t chosen, const char *name, phandle_t *node)
+{
+ char buf[64];
+
+ if (OF_getprop(chosen, name, buf, sizeof(buf)) <= 0)
+ return (ENXIO);
+ if ((*node = OF_finddevice(buf)) == -1)
+ return (ENXIO);
+
+ return (0);
+}
+
+static const struct ofw_compat_data *
+uart_fdt_find_compatible(phandle_t node, const struct ofw_compat_data *cd)
+{
+ const struct ofw_compat_data *ocd;
+
+ for (ocd = cd; ocd->ocd_str != NULL; ocd++) {
+ if (fdt_is_compatible(node, ocd->ocd_str))
+ return (ocd);
+ }
+ return (NULL);
+}
+
+static uintptr_t
+uart_fdt_find_by_node(phandle_t node, int class_list)
+{
+ struct ofw_compat_data **cd;
+ const struct ofw_compat_data *ocd;
+
+ if (class_list) {
+ SET_FOREACH(cd, uart_fdt_class_set) {
+ ocd = uart_fdt_find_compatible(node, *cd);
+ if ((ocd != NULL) && (ocd->ocd_data != 0))
+ return (ocd->ocd_data);
+ }
+ } else {
+ SET_FOREACH(cd, uart_fdt_class_and_device_set) {
+ ocd = uart_fdt_find_compatible(node, *cd);
+ if ((ocd != NULL) && (ocd->ocd_data != 0))
+ return (ocd->ocd_data);
+ }
+ }
+
+ return (0);
+}
+
+int
+uart_cpu_fdt_probe(struct uart_class **classp, bus_space_tag_t *bst,
+ bus_space_handle_t *bsh, int *baud, u_int *rclk, u_int *shiftp)
+{
+ const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout",
+ "stdin-path", "stdin", NULL};
+ const char **name;
+ struct uart_class *class;
+ phandle_t node, chosen;
+ pcell_t br, clk, shift;
+ char *cp;
+ int err;
+
+ /* Has the user forced a specific device node? */
+ cp = kern_getenv("hw.fdt.console");
+ if (cp == NULL) {
+ /*
+ * Retrieve /chosen/std{in,out}.
+ */
+ node = -1;
+ if ((chosen = OF_finddevice("/chosen")) != -1) {
+ for (name = propnames; *name != NULL; name++) {
+ if (phandle_chosen_propdev(chosen, *name,
+ &node) == 0)
+ break;
+ }
+ }
+ if (chosen == -1 || *name == NULL)
+ node = OF_finddevice("serial0"); /* Last ditch */
+ } else {
+ node = OF_finddevice(cp);
+ }
+
+ if (node == -1)
+ return (ENXIO);
+
+ /*
+ * Check old style of UART definition first. Unfortunately, the common
+ * FDT processing is not possible if we have clock, power domains and
+ * pinmux stuff.
+ */
+ class = (struct uart_class *)uart_fdt_find_by_node(node, 0);
+ if (class != NULL) {
+ if ((err = uart_fdt_get_clock(node, &clk)) != 0)
+ return (err);
+ } else {
+ /* Check class only linker set */
+ class =
+ (struct uart_class *)uart_fdt_find_by_node(node, 1);
+ if (class == NULL)
+ return (ENXIO);
+ clk = 0;
+ }
+
+ /*
+ * Retrieve serial attributes.
+ */
+ if (uart_fdt_get_shift(node, &shift) != 0)
+ shift = uart_getregshift(class);
+
+ if (OF_getencprop(node, "current-speed", &br, sizeof(br)) <= 0)
+ br = 0;
+
+ err = OF_decode_addr(node, 0, bst, bsh, NULL);
+ if (err != 0)
+ return (err);
+
+ *classp = class;
+ *baud = br;
+ *rclk = clk;
+ *shiftp = shift;
+
+ return (0);
+}
+
+static int
uart_fdt_probe(device_t dev)
{
struct uart_softc *sc;
Modified: stable/11/sys/dev/uart/uart_cpu_fdt.c
==============================================================================
--- stable/11/sys/dev/uart/uart_cpu_fdt.c Mon Apr 2 20:12:25 2018 (r331884)
+++ stable/11/sys/dev/uart/uart_cpu_fdt.c Mon Apr 2 20:47:55 2018 (r331885)
@@ -120,14 +120,11 @@ uart_fdt_find_by_node(phandle_t node, int class_list)
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
- const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout",
- "stdin-path", "stdin", NULL};
- const char **name;
struct uart_class *class;
- phandle_t node, chosen;
- pcell_t shift, br, rclk;
- char *cp;
- int err;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ u_int shift, rclk;
+ int br, err;
/* Allow overriding the FDT using the environment. */
class = &uart_ns8250_class;
@@ -138,69 +135,24 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
if (devtype != UART_DEV_CONSOLE)
return (ENXIO);
- /* Has the user forced a specific device node? */
- cp = kern_getenv("hw.fdt.console");
- if (cp == NULL) {
- /*
- * Retrieve /chosen/std{in,out}.
- */
- node = -1;
- if ((chosen = OF_finddevice("/chosen")) != -1) {
- for (name = propnames; *name != NULL; name++) {
- if (phandle_chosen_propdev(chosen, *name,
- &node) == 0)
- break;
- }
- }
- if (chosen == -1 || *name == NULL)
- node = OF_finddevice("serial0"); /* Last ditch */
- } else {
- node = OF_finddevice(cp);
- }
+ err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk, &shift);
+ if (err != 0)
+ return (err);
- if (node == -1) /* Can't find anything */
- return (ENXIO);
-
/*
- * Check old style of UART definition first. Unfortunately, the common
- * FDT processing is not possible if we have clock, power domains and
- * pinmux stuff.
- */
- class = (struct uart_class *)uart_fdt_find_by_node(node, 0);
- if (class != NULL) {
- if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
- return (err);
- } else {
- /* Check class only linker set */
- class =
- (struct uart_class *)uart_fdt_find_by_node(node, 1);
- if (class == NULL)
- return (ENXIO);
- rclk = 0;
- }
-
- /*
- * Retrieve serial attributes.
- */
- if (uart_fdt_get_shift(node, &shift) != 0)
- shift = uart_getregshift(class);
-
- if (OF_getencprop(node, "current-speed", &br, sizeof(br)) <= 0)
- br = 0;
-
- /*
* Finalize configuration.
*/
di->bas.chan = 0;
- di->bas.regshft = (u_int)shift;
+ di->bas.regshft = shift;
di->baudrate = br;
- di->bas.rclk = (u_int)rclk;
+ di->bas.rclk = rclk;
di->ops = uart_getops(class);
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
+ di->bas.bst = bst;
+ di->bas.bsh = bsh;
- err = OF_decode_addr(node, 0, &di->bas.bst, &di->bas.bsh, NULL);
uart_bus_space_mem = di->bas.bst;
uart_bus_space_io = NULL;
Modified: stable/11/sys/dev/uart/uart_cpu_fdt.h
==============================================================================
--- stable/11/sys/dev/uart/uart_cpu_fdt.h Mon Apr 2 20:12:25 2018 (r331884)
+++ stable/11/sys/dev/uart/uart_cpu_fdt.h Mon Apr 2 20:47:55 2018 (r331885)
@@ -50,6 +50,8 @@ SET_DECLARE(uart_fdt_class_set, struct ofw_compat_data
#define UART_FDT_CLASS(data) \
DATA_SET(uart_fdt_class_set, data)
+int uart_cpu_fdt_probe(struct uart_class **, bus_space_tag_t *,
+ bus_space_handle_t *, int *, u_int *, u_int *);
int uart_fdt_get_clock(phandle_t node, pcell_t *cell);
int uart_fdt_get_shift(phandle_t node, pcell_t *cell);
More information about the svn-src-stable-11
mailing list