diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c --- a/sys/dev/uart/uart_bus_fdt.c +++ b/sys/dev/uart/uart_bus_fdt.c @@ -169,52 +169,62 @@ return (0); } +phandle_t +uart_fdt_get_node(const int devtype) +{ + const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout", + "stdin-path", "stdin", NULL}; + const char *propnames_dbgport[] = {"freebsd,debug-path", NULL}; + const char **name; + char *cp = NULL; + phandle_t node, chosen; + + /* Has the user forced a specific device node? */ + switch (devtype) { + case UART_DEV_DBGPORT: + cp = kern_getenv("hw.fdt.dbgport"); + name = propnames_dbgport; + break; + case UART_DEV_CONSOLE: + cp = kern_getenv("hw.fdt.console"); + name = propnames; + break; + default: + return (-1); + } + + if (cp == NULL) { + /* + * Retrieve a node from /chosen. + */ + node = -1; + if ((chosen = OF_finddevice("/chosen")) != -1) { + for (; *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); + } + + return (node); +} + 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, u_int *iowidthp, const int devtype) { - const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout", - "stdin-path", "stdin", NULL}; - const char *propnames_dbgport[] = {"freebsd,debug-path", NULL}; - const char **name; struct uart_class *class; - phandle_t node, chosen; + phandle_t node; pcell_t br, clk, shift, iowidth; - char *cp = NULL; int err; - /* Has the user forced a specific device node? */ - switch (devtype) { - case UART_DEV_DBGPORT: - cp = kern_getenv("hw.fdt.dbgport"); - name = propnames_dbgport; - break; - case UART_DEV_CONSOLE: - cp = kern_getenv("hw.fdt.console"); - name = propnames; - break; - default: - return (ENXIO); - } - - if (cp == NULL) { - /* - * Retrieve a node from /chosen. - */ - node = -1; - if ((chosen = OF_finddevice("/chosen")) != -1) { - for (; *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); - } + node = uart_fdt_get_node(devtype); if (node == -1) return (ENXIO); diff --git a/sys/dev/uart/uart_cpu_fdt.h b/sys/dev/uart/uart_cpu_fdt.h --- a/sys/dev/uart/uart_cpu_fdt.h +++ b/sys/dev/uart/uart_cpu_fdt.h @@ -53,5 +53,6 @@ int uart_fdt_get_clock(phandle_t node, pcell_t *cell); int uart_fdt_get_shift(phandle_t node, pcell_t *cell); int uart_fdt_get_io_width(phandle_t node, pcell_t *cell); +phandle_t uart_fdt_get_node(const int); #endif /* _DEV_UART_CPU_FDT_H_ */ diff --git a/sys/dev/uart/uart_dev_ns8250.h b/sys/dev/uart/uart_dev_ns8250.h --- a/sys/dev/uart/uart_dev_ns8250.h +++ b/sys/dev/uart/uart_dev_ns8250.h @@ -59,5 +59,11 @@ void ns8250_bus_grab(struct uart_softc *); bool ns8250_bus_txbusy(struct uart_softc *); void ns8250_bus_ungrab(struct uart_softc *); +int ns8250_probe(struct uart_bas *bas); +void ns8250_init(struct uart_bas *bas, int, int, int, int); +void ns8250_term(struct uart_bas *bas); +void ns8250_putc(struct uart_bas *bas, int); +int ns8250_rxready(struct uart_bas *bas); +int ns8250_getc(struct uart_bas *bas, struct mtx *); #endif /* _DEV_UART_DEV_NS8250_H_ */ diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -305,12 +305,6 @@ /* * Low-level UART interface. */ -static int ns8250_probe(struct uart_bas *bas); -static void ns8250_init(struct uart_bas *bas, int, int, int, int); -static void ns8250_term(struct uart_bas *bas); -static void ns8250_putc(struct uart_bas *bas, int); -static int ns8250_rxready(struct uart_bas *bas); -static int ns8250_getc(struct uart_bas *bas, struct mtx *); struct uart_ops uart_ns8250_ops = { .probe = ns8250_probe, @@ -321,7 +315,7 @@ .getc = ns8250_getc, }; -static int +int ns8250_probe(struct uart_bas *bas) { u_char val; @@ -343,7 +337,7 @@ return (0); } -static void +void ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, int parity) { @@ -374,7 +368,7 @@ ns8250_clrint(bas); } -static void +void ns8250_term(struct uart_bas *bas) { @@ -383,7 +377,7 @@ uart_barrier(bas); } -static void +void ns8250_putc(struct uart_bas *bas, int c) { int limit; @@ -397,14 +391,14 @@ uart_barrier(bas); } -static int +int ns8250_rxready(struct uart_bas *bas) { return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); } -static int +int ns8250_getc(struct uart_bas *bas, struct mtx *hwmtx) { int c; diff --git a/sys/dev/uart/uart_dev_snps.c b/sys/dev/uart/uart_dev_snps.c --- a/sys/dev/uart/uart_dev_snps.c +++ b/sys/dev/uart/uart_dev_snps.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -104,11 +105,22 @@ KOBJMETHOD_END }; +static int uart_snps_probe(struct uart_bas *bas); + +struct uart_ops uart_snps_ops = { + .probe = uart_snps_probe, + .init = ns8250_init, + .term = ns8250_term, + .putc = ns8250_putc, + .rxready = ns8250_rxready, + .getc = ns8250_getc, +}; + struct uart_class uart_snps_class = { "snps", snps_methods, sizeof(struct snps_softc), - .uc_ops = &uart_ns8250_ops, + .uc_ops = &uart_snps_ops, .uc_range = 8, .uc_rclk = 0, }; @@ -120,6 +132,23 @@ }; UART_FDT_CLASS(compat_data); +static int +uart_snps_probe(struct uart_bas *bas) +{ + phandle_t node; + int devtype = UART_DEV_CONSOLE; + int err; + + if (ns8250_probe(bas) == 0) { + node = uart_fdt_get_node(devtype); + if (node != -1) { + if ((err = uart_fdt_get_clock(node, &bas->rclk)) != 0) + return (err); + } + } + return (0); +} + static int snps_get_clocks(device_t dev, clk_t *baudclk, clk_t *apb_pclk) {