summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-13 19:09:00 +0000
committerian <ian@FreeBSD.org>2014-05-13 19:09:00 +0000
commit7d01a916d944df2168da8a3a096c4d6986b1fa3a (patch)
tree76196f08b686e04851e0e8c012696ea59f3a365e /sys/dev
parent7efcec89766718e9a5f210d57b86cf5791d12278 (diff)
downloadFreeBSD-src-7d01a916d944df2168da8a3a096c4d6986b1fa3a.zip
FreeBSD-src-7d01a916d944df2168da8a3a096c4d6986b1fa3a.tar.gz
MFC r257111, r257144, r257157, r257183
Test UARTs physical address instead of virtual. Be a bit more flexible in how we find the console from the properties on /chosen, following the list of allowed console properties in ePAPR. Also do not require that stdin be defined and equal to stdout: stdin is nonstandard (for ePAPR) and console in an unexpected place is after all better than no console.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/uart/uart_cpu_fdt.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/sys/dev/uart/uart_cpu_fdt.c b/sys/dev/uart/uart_cpu_fdt.c
index 112593f..b063cb4 100644
--- a/sys/dev/uart/uart_cpu_fdt.c
+++ b/sys/dev/uart/uart_cpu_fdt.c
@@ -36,6 +36,10 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/fdt.h>
@@ -88,13 +92,34 @@ int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
- return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+ if (b1->bst != b2->bst)
+ return (0);
+ if (pmap_kextract(b1->bsh) == 0)
+ return (0);
+ if (pmap_kextract(b2->bsh) == 0)
+ return (0);
+ return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0);
+}
+
+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);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
- char buf[64];
+ const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout",
+ "stdin-path", "stdin", NULL};
+ const char **name;
const struct ofw_compat_data *cd;
struct uart_class *class;
phandle_t node, chosen;
@@ -105,7 +130,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
uart_bus_space_mem = fdtbus_bs_tag;
uart_bus_space_io = NULL;
- /* Allow overriding the FDT uning the environment. */
+ /* Allow overriding the FDT using the environment. */
class = &uart_ns8250_class;
err = uart_getenv(devtype, di, class);
if (!err)
@@ -119,14 +144,11 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
*/
if ((chosen = OF_finddevice("/chosen")) == -1)
return (ENXIO);
- if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0)
- return (ENXIO);
- if ((node = OF_finddevice(buf)) == -1)
- return (ENXIO);
- if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0)
- return (ENXIO);
- if (OF_finddevice(buf) != node)
- /* Only stdin == stdout is supported. */
+ for (name = propnames; *name != NULL; name++) {
+ if (phandle_chosen_propdev(chosen, *name, &node) == 0)
+ break;
+ }
+ if (*name == NULL)
return (ENXIO);
/*
* Retrieve serial attributes.
OpenPOWER on IntegriCloud