svn commit: r304970 - in head/sys/dev: ofw uart
Justin Hibbits
jhibbits at FreeBSD.org
Sun Aug 28 21:31:22 UTC 2016
Author: jhibbits
Date: Sun Aug 28 21:31:21 2016
New Revision: 304970
URL: https://svnweb.freebsd.org/changeset/base/304970
Log:
Check all compatible strings on uart devices in powerpc
Summary:
Some device trees put "fsl,ns16650" first in the compatible list. This causes
the probe code to choke, even though the device is compatible with ns16650, and
has it listed later in the tree.
Reviewed by: nwhitehorn
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D7676
Modified:
head/sys/dev/ofw/ofw_bus_subr.c
head/sys/dev/ofw/ofw_bus_subr.h
head/sys/dev/uart/uart_cpu_powerpc.c
Modified: head/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.c Sun Aug 28 21:26:11 2016 (r304969)
+++ head/sys/dev/ofw/ofw_bus_subr.c Sun Aug 28 21:31:21 2016 (r304970)
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include "ofw_bus_if.h"
+#define OFW_COMPAT_LEN 255
+
int
ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *obd, phandle_t node)
{
@@ -178,7 +180,8 @@ ofw_bus_status_okay(device_t dev)
}
static int
-ofw_bus_node_is_compatible(const char *compat, int len, const char *onecompat)
+ofw_bus_node_is_compatible_int(const char *compat, int len,
+ const char *onecompat)
{
int onelen, l, ret;
@@ -203,6 +206,25 @@ ofw_bus_node_is_compatible(const char *c
}
int
+ofw_bus_node_is_compatible(phandle_t node, const char *compatstr)
+{
+ char compat[OFW_COMPAT_LEN];
+ int len, rv;
+
+ if ((len = OF_getproplen(node, "compatible")) <= 0)
+ return (0);
+
+ bzero(compat, OFW_COMPAT_LEN);
+
+ if (OF_getprop(node, "compatible", compat, OFW_COMPAT_LEN) < 0)
+ return (0);
+
+ rv = ofw_bus_node_is_compatible_int(compat, len, compatstr);
+
+ return (rv);
+}
+
+int
ofw_bus_is_compatible(device_t dev, const char *onecompat)
{
phandle_t node;
@@ -219,7 +241,7 @@ ofw_bus_is_compatible(device_t dev, cons
if ((len = OF_getproplen(node, "compatible")) <= 0)
return (0);
- return (ofw_bus_node_is_compatible(compat, len, onecompat));
+ return (ofw_bus_node_is_compatible_int(compat, len, onecompat));
}
int
@@ -689,7 +711,7 @@ ofw_bus_find_compatible(phandle_t node,
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
len = OF_getprop_alloc(child, "compatible", 1, &compat);
if (len >= 0) {
- ret = ofw_bus_node_is_compatible(compat, len,
+ ret = ofw_bus_node_is_compatible_int(compat, len,
onecompat);
free(compat, M_OFWPROP);
if (ret != 0)
Modified: head/sys/dev/ofw/ofw_bus_subr.h
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.h Sun Aug 28 21:26:11 2016 (r304969)
+++ head/sys/dev/ofw/ofw_bus_subr.h Sun Aug 28 21:31:21 2016 (r304970)
@@ -107,6 +107,7 @@ phandle_t ofw_bus_find_iparent(phandle_t
/* Helper routine for checking compat prop */
int ofw_bus_is_compatible(device_t, const char *);
int ofw_bus_is_compatible_strict(device_t, const char *);
+int ofw_bus_node_is_compatible(phandle_t, const char *);
/*
* Helper routine to search a list of compat properties. The table is
Modified: head/sys/dev/uart/uart_cpu_powerpc.c
==============================================================================
--- head/sys/dev/uart/uart_cpu_powerpc.c Sun Aug 28 21:26:11 2016 (r304969)
+++ head/sys/dev/uart/uart_cpu_powerpc.c Sun Aug 28 21:31:21 2016 (r304970)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/ofw_machdep.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
@@ -163,14 +164,13 @@ uart_cpu_getdev(int devtype, struct uart
return (ENXIO);
if (strcmp(buf, "serial") != 0)
return (ENXIO);
- if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
- return (ENXIO);
- if (strncmp(buf, "chrp,es", 7) == 0) {
+ if (ofw_bus_node_is_compatible(input, "chrp,es")) {
class = &uart_z8530_class;
di->bas.regshft = 4;
di->bas.chan = 1;
- } else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
+ } else if (ofw_bus_node_is_compatible(input,"ns16550") ||
+ ofw_bus_node_is_compatible(input,"ns8250")) {
class = &uart_ns8250_class;
di->bas.regshft = 0;
di->bas.chan = 0;
More information about the svn-src-head
mailing list