@@ -247,6 +247,7 @@ F: docs/misc/arm/
F: xen/arch/arm/
F: xen/drivers/char/arm-uart.c
F: xen/drivers/char/cadence-uart.c
+F: xen/drivers/char/dt-uart.c
F: xen/drivers/char/exynos4210-uart.c
F: xen/drivers/char/imx-lpuart.c
F: xen/drivers/char/meson-uart.c
@@ -15,3 +15,4 @@ obj-$(CONFIG_ARM) += arm-uart.o
obj-y += serial.o
obj-$(CONFIG_XEN_GUEST) += xen_pv_console.o
obj-$(CONFIG_PV_SHIM) += consoled.o
+obj-$(CONFIG_HAS_DEVICE_TREE) += dt-uart.o
@@ -19,89 +19,9 @@
#include <asm/device.h>
-#include <xen/console.h>
-#include <xen/device_tree.h>
-#include <xen/param.h>
#include <xen/serial.h>
-#include <xen/errno.h>
#include <xen/acpi.h>
-/*
- * Configure UART port with a string:
- * path:options
- *
- * @path: full path used in the device tree for the UART. If the path
- * doesn't start with '/', we assuming that it's an alias.
- * @options: UART speficic options (see in each UART driver)
- */
-static char __initdata opt_dtuart[256] = "";
-string_param("dtuart", opt_dtuart);
-
-static void __init dt_uart_init(void)
-{
- struct dt_device_node *dev;
- int ret;
- const char *devpath = opt_dtuart;
- const char *options;
- char *split;
-
- if ( !console_has("dtuart") )
- return; /* Not for us */
-
- if ( !strcmp(opt_dtuart, "") )
- {
- const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
-
- if ( chosen )
- {
- const char *stdout;
-
- ret = dt_property_read_string(chosen, "stdout-path", &stdout);
- if ( ret >= 0 )
- {
- printk("Taking dtuart configuration from /chosen/stdout-path\n");
- if ( strlcpy(opt_dtuart, stdout, sizeof(opt_dtuart))
- >= sizeof(opt_dtuart) )
- printk("WARNING: /chosen/stdout-path too long, truncated\n");
- }
- else if ( ret != -EINVAL /* Not present */ )
- printk("Failed to read /chosen/stdout-path (%d)\n", ret);
- }
- }
-
- if ( !strcmp(opt_dtuart, "") )
- {
- printk("No dtuart path configured\n");
- return;
- }
-
- split = strchr(opt_dtuart, ':');
- if ( split )
- {
- split[0] = '\0';
- options = split + 1;
- }
- else
- options = "";
-
- printk("Looking for dtuart at \"%s\", options \"%s\"\n", devpath, options);
- if ( *devpath == '/' )
- dev = dt_find_node_by_path(devpath);
- else
- dev = dt_find_node_by_alias(devpath);
-
- if ( !dev )
- {
- printk("Unable to find device \"%s\"\n", devpath);
- return;
- }
-
- ret = device_init(dev, DEVICE_SERIAL, options);
-
- if ( ret )
- printk("Unable to initialize dtuart: %d\n", ret);
-}
-
#ifdef CONFIG_ACPI
static void __init acpi_uart_init(void)
{
new file mode 100644
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <xen/console.h>
+#include <xen/device_tree.h>
+#include <xen/errno.h>
+#include <xen/param.h>
+#include <xen/serial.h>
+
+#include <asm/device.h>
+
+/*
+ * Configure UART port with a string:
+ * path:options
+ *
+ * @path: full path used in the device tree for the UART. If the path
+ * doesn't start with '/', we assuming that it's an alias.
+ * @options: UART speficic options (see in each UART driver)
+ */
+static char __initdata opt_dtuart[256] = "";
+string_param("dtuart", opt_dtuart);
+
+void __init dt_uart_init(void)
+{
+ struct dt_device_node *dev;
+ int ret;
+ const char *devpath = opt_dtuart;
+ const char *options;
+ char *split;
+
+ if ( !console_has("dtuart") )
+ return; /* Not for us */
+
+ if ( !strcmp(opt_dtuart, "") )
+ {
+ const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
+
+ if ( chosen )
+ {
+ const char *stdout;
+
+ ret = dt_property_read_string(chosen, "stdout-path", &stdout);
+ if ( ret >= 0 )
+ {
+ printk("Taking dtuart configuration from /chosen/stdout-path\n");
+ if ( strlcpy(opt_dtuart, stdout, sizeof(opt_dtuart))
+ >= sizeof(opt_dtuart) )
+ printk("WARNING: /chosen/stdout-path too long, truncated\n");
+ }
+ else if ( ret != -EINVAL /* Not present */ )
+ printk("Failed to read /chosen/stdout-path (%d)\n", ret);
+ }
+ }
+
+ if ( !strcmp(opt_dtuart, "") )
+ {
+ printk("No dtuart path configured\n");
+ return;
+ }
+
+ split = strchr(opt_dtuart, ':');
+ if ( split )
+ {
+ split[0] = '\0';
+ options = split + 1;
+ }
+ else
+ options = "";
+
+ printk("Looking for dtuart at \"%s\", options \"%s\"\n", devpath, options);
+ if ( *devpath == '/' )
+ dev = dt_find_node_by_path(devpath);
+ else
+ dev = dt_find_node_by_alias(devpath);
+
+ if ( !dev )
+ {
+ printk("Unable to find device \"%s\"\n", devpath);
+ return;
+ }
+
+ ret = device_init(dev, DEVICE_SERIAL, options);
+
+ if ( ret )
+ printk("Unable to initialize dtuart: %d\n", ret);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
\ No newline at end of file
@@ -168,6 +168,8 @@ static void inline xhci_dbc_uart_init(void) {}
void arm_uart_init(void);
+void dt_uart_init(void);
+
struct physdev_dbgp_op;
int dbgp_op(const struct physdev_dbgp_op *op);
The `dt_uart_init()` functions is relocated to a new file `dt-uart.c` to allow for reuse across architectures that utilize the device tree to describe hardware components. RISC-V is going to follow the same approach to UART initialization, which includes checking for the presence of `dtuart` in the console string or verifying the `stdout-path` property in the `/chosen` node, followed by searching for the UART node and calling `device_init()` for UART setup. Add `xen/drivers/char/dt-uart.c` to the ARM ARCHITECTURE section in the MAINTAINERS file, as ARM maintainers are best suited to maintain this code. No functional change. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- MAINTAINERS | 1 + xen/drivers/char/Makefile | 1 + xen/drivers/char/arm-uart.c | 80 ------------------------------- xen/drivers/char/dt-uart.c | 95 +++++++++++++++++++++++++++++++++++++ xen/include/xen/serial.h | 2 + 5 files changed, 99 insertions(+), 80 deletions(-) create mode 100644 xen/drivers/char/dt-uart.c