Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142880310
D1992.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D1992.diff
View Options
Index: sys/dev/uart/uart.h
===================================================================
--- sys/dev/uart/uart.h
+++ sys/dev/uart/uart.h
@@ -80,10 +80,6 @@
extern struct uart_class at91_usart_class __attribute__((weak));
extern struct uart_class uart_exynos4210_class __attribute__((weak));
-#ifdef FDT
-struct ofw_compat_data;
-extern const struct ofw_compat_data *uart_fdt_compat_data;
-#endif
#ifdef PC98
struct uart_class *uart_pc98_getdev(u_long port);
Index: sys/dev/uart/uart_bus_fdt.c
===================================================================
--- sys/dev/uart/uart_bus_fdt.c
+++ sys/dev/uart/uart_bus_fdt.c
@@ -45,6 +45,7 @@
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
static int uart_fdt_probe(device_t);
@@ -91,7 +92,7 @@
};
/* Export the compat_data table for use by the uart_cpu_fdt.c probe routine. */
-const struct ofw_compat_data *uart_fdt_compat_data = compat_data;
+UART_FDT_CLASS_AND_DEVICE(compat_data);
static int
uart_fdt_get_clock(phandle_t node, pcell_t *cell)
@@ -127,6 +128,20 @@
return (0);
}
+static uintptr_t
+uart_fdt_find_device(device_t dev)
+{
+ struct ofw_compat_data **cd;
+ const struct ofw_compat_data *ocd;
+
+ SET_FOREACH(cd, uart_fdt_class_and_device_set) {
+ ocd = ofw_bus_search_compatible(dev, *cd);
+ if (ocd->ocd_data != 0)
+ return (ocd->ocd_data);
+ }
+ return (0);
+}
+
static int
uart_fdt_probe(device_t dev)
{
@@ -134,19 +149,16 @@
phandle_t node;
pcell_t clock, shift;
int err;
- const struct ofw_compat_data * cd;
sc = device_get_softc(dev);
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- cd = ofw_bus_search_compatible(dev, compat_data);
- if (cd->ocd_data == (uintptr_t)NULL)
+ sc->sc_class = (struct uart_class *)uart_fdt_find_device(dev);
+ if (sc->sc_class == NULL)
return (ENXIO);
- sc->sc_class = (struct uart_class *)cd->ocd_data;
-
node = ofw_bus_get_node(dev);
if ((err = uart_fdt_get_clock(node, &clock)) != 0)
Index: sys/dev/uart/uart_cpu_fdt.h
===================================================================
--- /dev/null
+++ sys/dev/uart/uart_cpu_fdt.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright 1992-2014 The FreeBSD Project. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_UART_CPU_FDT_H_
+#define _DEV_UART_CPU_FDT_H_
+
+#include <sys/linker_set.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+
+/*
+ * If your UART driver implements only uart_class and uses uart_cpu_fdt.c
+ * for device instationation, then use UART_FDT_CLASS_AND_DEVICE for its
+ * declaration
+ */
+SET_DECLARE(uart_fdt_class_and_device_set, struct ofw_compat_data );
+#define UART_FDT_CLASS_AND_DEVICE(data) \
+ DATA_SET(uart_fdt_class_and_device_set, data)
+
+/*
+ * If your UART driver implements uart_class and custom device layer,
+ * then use UART_FDT_CLASS for its declaration
+ */
+SET_DECLARE(uart_fdt_class_set, struct ofw_compat_data );
+#define UART_FDT_CLASS(data) \
+ DATA_SET(uart_fdt_class_set, data)
+
+
+#endif /* _DEV_UART_CPU_FDT_H_ */
Index: sys/dev/uart/uart_cpu_fdt.c
===================================================================
--- sys/dev/uart/uart_cpu_fdt.c
+++ sys/dev/uart/uart_cpu_fdt.c
@@ -50,6 +50,7 @@
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
/*
* UART console routines.
@@ -115,13 +116,46 @@
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_getdev(int devtype, struct uart_devinfo *di)
{
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;
pcell_t shift, br, rclk;
@@ -160,24 +194,32 @@
* 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);
+ else
+ br = fdt32_to_cpu(br);
- if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
- return (err);
/*
- * Finalize configuration.
+ * Check old style of UART definition first. Unfortunately, the common
+ * FDT processing is not possible if we have clock, power domains and
+ * pinmux stuff.
*/
- for (cd = uart_fdt_compat_data; cd->ocd_str != NULL; ++cd) {
- if (fdt_is_compatible(node, cd->ocd_str))
- break;
+ 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;
}
- if (cd->ocd_str == NULL)
- return (ENXIO);
- class = (struct uart_class *)cd->ocd_data;
+ /*
+ * Finalize configuration.
+ */
di->bas.chan = 0;
di->bas.regshft = (u_int)shift;
di->baudrate = br;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 25, 10:39 AM (4 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27936207
Default Alt Text
D1992.diff (6 KB)
Attached To
Mode
D1992: Use linker sets for definition of FDT UARTs
Attached
Detach File
Event Timeline
Log In to Comment