summaryrefslogtreecommitdiff
path: root/sys/dev/uart
diff options
context:
space:
mode:
authorMatt Macy <mmacy@FreeBSD.org>2018-08-19 21:10:21 +0000
committerMatt Macy <mmacy@FreeBSD.org>2018-08-19 21:10:21 +0000
commit381388b9c48b07b08199b07b7657d46e8fcb59b0 (patch)
treea95a9c1e5dc8cd866c7f14db66b0439bc7156de2 /sys/dev/uart
parent8d67357c5c5896446984f206fec86f818aa1c22c (diff)
Notes
Diffstat (limited to 'sys/dev/uart')
-rw-r--r--sys/dev/uart/uart_bus.h5
-rw-r--r--sys/dev/uart/uart_bus_acpi.c49
-rw-r--r--sys/dev/uart/uart_bus_ebus.c2
-rw-r--r--sys/dev/uart/uart_bus_fdt.c2
-rw-r--r--sys/dev/uart/uart_bus_isa.c2
-rw-r--r--sys/dev/uart/uart_bus_pccard.c2
-rw-r--r--sys/dev/uart/uart_bus_pci.c2
-rw-r--r--sys/dev/uart/uart_bus_puc.c2
-rw-r--r--sys/dev/uart/uart_bus_scc.c2
-rw-r--r--sys/dev/uart/uart_core.c3
-rw-r--r--sys/dev/uart/uart_cpu_acpi.h12
-rw-r--r--sys/dev/uart/uart_cpu_arm64.c10
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c24
-rw-r--r--sys/dev/uart/uart_dev_pl011.c6
-rw-r--r--sys/dev/uart/uart_dev_snps.c17
15 files changed, 69 insertions, 71 deletions
diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h
index 556a9228493ca..2bc33734cfb51 100644
--- a/sys/dev/uart/uart_bus.h
+++ b/sys/dev/uart/uart_bus.h
@@ -56,6 +56,9 @@
#define UART_IOCTL_OFLOW 3
#define UART_IOCTL_BAUD 4
+/* UART quirk flags */
+#define UART_F_BUSY_DETECT 0x1
+
/*
* UART class & instance (=softc)
*/
@@ -140,7 +143,7 @@ int uart_bus_detach(device_t dev);
int uart_bus_resume(device_t dev);
serdev_intr_t *uart_bus_ihand(device_t dev, int ipend);
int uart_bus_ipend(device_t dev);
-int uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan);
+int uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan, int quirks);
int uart_bus_sysdev(device_t dev);
void uart_sched_softih(struct uart_softc *, uint32_t);
diff --git a/sys/dev/uart/uart_bus_acpi.c b/sys/dev/uart/uart_bus_acpi.c
index 88b1480064f4b..a711c0c6a675e 100644
--- a/sys/dev/uart/uart_bus_acpi.c
+++ b/sys/dev/uart/uart_bus_acpi.c
@@ -37,17 +37,13 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/resource.h>
-#include <isa/isavar.h>
-
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu_acpi.h>
-
-#ifdef __aarch64__
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
-#endif
+
static int uart_acpi_probe(device_t dev);
@@ -66,59 +62,40 @@ static driver_t uart_acpi_driver = {
sizeof(struct uart_softc),
};
-#if defined(__i386__) || defined(__amd64__)
-static struct isa_pnp_id acpi_ns8250_ids[] = {
- {0x0005d041, "Standard PC COM port"}, /* PNP0500 */
- {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */
- {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */
- {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */
- {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */
- {0x04f0235c, "Wacom Tablet PC Screen"}, /* WACF004 */
- {0x0ef0235c, "Wacom Tablet PC Screen 00e"}, /* WACF00e */
- {0xe502aa1a, "Wacom Tablet at FuS Lifebook T"}, /* FUJ02E5 */
- {0}
-};
-#endif
-
-#ifdef __aarch64__
-static struct uart_class *
+static struct acpi_uart_compat_data *
uart_acpi_find_device(device_t dev)
{
- struct acpi_uart_compat_data **cd;
+ struct acpi_uart_compat_data **cd, *cd_it;
ACPI_HANDLE h;
if ((h = acpi_get_handle(dev)) == NULL)
return (NULL);
SET_FOREACH(cd, uart_acpi_class_and_device_set) {
- if (acpi_MatchHid(h, (*cd)->hid)) {
- return ((*cd)->clas);
+ for (cd_it = *cd; cd_it->cd_hid != NULL; cd_it++) {
+ if (acpi_MatchHid(h, cd_it->cd_hid))
+ return (cd_it);
}
}
return (NULL);
}
-#endif
static int
uart_acpi_probe(device_t dev)
{
struct uart_softc *sc;
+ struct acpi_uart_compat_data *cd;
sc = device_get_softc(dev);
-#if defined(__i386__) || defined(__amd64__)
- if (!ISA_PNP_PROBE(device_get_parent(dev), dev, acpi_ns8250_ids)) {
- sc->sc_class = &uart_ns8250_class;
- return (uart_bus_probe(dev, 0, 0, 0, 0, 0));
+ if ((cd = uart_acpi_find_device(dev)) != NULL) {
+ sc->sc_class = cd->cd_class;
+ if (cd->cd_desc != NULL)
+ device_set_desc(dev, cd->cd_desc);
+ return (uart_bus_probe(dev, cd->cd_regshft, cd->cd_regiowidth,
+ cd->cd_rclk, 0, 0, cd->cd_quirks));
}
-
- /* Add checks for non-ns8250 IDs here. */
-#elif defined(__aarch64__)
- if ((sc->sc_class = uart_acpi_find_device(dev)) != NULL)
- return (uart_bus_probe(dev, 2, 0, 0, 0, 0));
-#endif
-
return (ENXIO);
}
diff --git a/sys/dev/uart/uart_bus_ebus.c b/sys/dev/uart/uart_bus_ebus.c
index dead7733d0cfb..dd50ff83596f3 100644
--- a/sys/dev/uart/uart_bus_ebus.c
+++ b/sys/dev/uart/uart_bus_ebus.c
@@ -99,7 +99,7 @@ uart_ebus_probe(device_t dev)
return (ENXIO);
}
sc->sc_class = &uart_ns8250_class;
- return (uart_bus_probe(dev, 0, 0, 0, 0, 0));
+ return (uart_bus_probe(dev, 0, 0, 0, 0, 0, 0));
}
return (ENXIO);
diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c
index 8efb7d7b2290e..34c600301e643 100644
--- a/sys/dev/uart/uart_bus_fdt.c
+++ b/sys/dev/uart/uart_bus_fdt.c
@@ -278,7 +278,7 @@ uart_fdt_probe(device_t dev)
if (uart_fdt_get_io_width(node, &iowidth) != 0)
iowidth = uart_getregiowidth(sc->sc_class);
- return (uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0));
+ return (uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0, 0));
}
DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0);
diff --git a/sys/dev/uart/uart_bus_isa.c b/sys/dev/uart/uart_bus_isa.c
index 759d4f92a9a9c..5085ff66fe102 100644
--- a/sys/dev/uart/uart_bus_isa.c
+++ b/sys/dev/uart/uart_bus_isa.c
@@ -168,7 +168,7 @@ uart_isa_probe(device_t dev)
/* Probe PnP _and_ non-PnP ns8250 here. */
sc->sc_class = &uart_ns8250_class;
- return (uart_bus_probe(dev, 0, 0, 0, 0, 0));
+ return (uart_bus_probe(dev, 0, 0, 0, 0, 0, 0));
}
DRIVER_MODULE(uart, isa, uart_isa_driver, uart_devclass, 0, 0);
diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c
index 894240ee344b8..3a8446a871f65 100644
--- a/sys/dev/uart/uart_bus_pccard.c
+++ b/sys/dev/uart/uart_bus_pccard.c
@@ -95,7 +95,7 @@ uart_pccard_attach(device_t dev)
sc = device_get_softc(dev);
sc->sc_class = &uart_ns8250_class;
- error = uart_bus_probe(dev, 0, 0, 0, 0, 0);
+ error = uart_bus_probe(dev, 0, 0, 0, 0, 0, 0);
if (error > 0)
return (error);
return (uart_bus_attach(dev));
diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c
index a8b8a7ec9ae19..f4be108ab7b26 100644
--- a/sys/dev/uart/uart_bus_pci.c
+++ b/sys/dev/uart/uart_bus_pci.c
@@ -206,7 +206,7 @@ uart_pci_probe(device_t dev)
return (ENXIO);
match:
- result = uart_bus_probe(dev, id->regshft, 0, id->rclk, id->rid, 0);
+ result = uart_bus_probe(dev, id->regshft, 0, id->rclk, id->rid, 0, 0);
/* Bail out on error. */
if (result > 0)
return (result);
diff --git a/sys/dev/uart/uart_bus_puc.c b/sys/dev/uart/uart_bus_puc.c
index 36419d43f3550..a90e01628f40e 100644
--- a/sys/dev/uart/uart_bus_puc.c
+++ b/sys/dev/uart/uart_bus_puc.c
@@ -83,7 +83,7 @@ uart_puc_probe(device_t dev)
if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk))
rclk = 0;
- return (uart_bus_probe(dev, 0, 0, rclk, 0, 0));
+ return (uart_bus_probe(dev, 0, 0, rclk, 0, 0, 0));
}
DRIVER_MODULE(uart, puc, uart_puc_driver, uart_devclass, 0, 0);
diff --git a/sys/dev/uart/uart_bus_scc.c b/sys/dev/uart/uart_bus_scc.c
index 80f590610d9da..6666a35e272e1 100644
--- a/sys/dev/uart/uart_bus_scc.c
+++ b/sys/dev/uart/uart_bus_scc.c
@@ -114,7 +114,7 @@ uart_scc_probe(device_t dev)
BUS_READ_IVAR(parent, dev, SCC_IVAR_REGSHFT, &rs))
return (ENXIO);
- return (uart_bus_probe(dev, rs, 0, cl, 0, ch));
+ return (uart_bus_probe(dev, rs, 0, cl, 0, ch, 0));
}
DRIVER_MODULE(uart, scc, uart_scc_driver, uart_devclass, 0, 0);
diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c
index fe722cb3eb2d9..87874e4d11d0f 100644
--- a/sys/dev/uart/uart_core.c
+++ b/sys/dev/uart/uart_core.c
@@ -493,7 +493,7 @@ uart_bus_sysdev(device_t dev)
}
int
-uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan)
+uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan, int quirks)
{
struct uart_softc *sc;
struct uart_devinfo *sysdev;
@@ -553,6 +553,7 @@ uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int
sc->sc_bas.regshft = regshft;
sc->sc_bas.regiowidth = regiowidth;
sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk;
+ sc->sc_bas.busy_detect = !!(quirks & UART_F_BUSY_DETECT);
SLIST_FOREACH(sysdev, &uart_sysdevs, next) {
if (chan == sysdev->bas.chan &&
diff --git a/sys/dev/uart/uart_cpu_acpi.h b/sys/dev/uart/uart_cpu_acpi.h
index 30cfa4e193883..416ff48f92661 100644
--- a/sys/dev/uart/uart_cpu_acpi.h
+++ b/sys/dev/uart/uart_cpu_acpi.h
@@ -38,9 +38,15 @@
struct uart_class;
struct acpi_uart_compat_data {
- const char *hid;
- struct uart_class *clas;
- uint16_t port_subtype;
+ const char *cd_hid;
+ struct uart_class *cd_class;
+
+ uint16_t cd_port_subtype;
+ int cd_regshft;
+ int cd_regiowidth;
+ int cd_rclk;
+ int cd_quirks;
+ const char *cd_desc;
};
/*
diff --git a/sys/dev/uart/uart_cpu_arm64.c b/sys/dev/uart/uart_cpu_arm64.c
index 56a88f73b2bf6..5a323a38ac4ea 100644
--- a/sys/dev/uart/uart_cpu_arm64.c
+++ b/sys/dev/uart/uart_cpu_arm64.c
@@ -88,16 +88,16 @@ uart_cpu_acpi_scan(uint8_t interface_type)
SET_FOREACH(cd, uart_acpi_class_and_device_set) {
curcd = *cd;
- for (i = 0; curcd[i].hid != NULL; i++) {
- if (curcd[i].port_subtype == interface_type)
+ for (i = 0; curcd[i].cd_hid != NULL; i++) {
+ if (curcd[i].cd_port_subtype == interface_type)
return (&curcd[i]);
}
}
SET_FOREACH(cd, uart_acpi_class_set) {
curcd = *cd;
- for (i = 0; curcd[i].hid != NULL; i++) {
- if (curcd[i].port_subtype == interface_type)
+ for (i = 0; curcd[i].cd_hid != NULL; i++) {
+ if (curcd[i].cd_port_subtype == interface_type)
return (&curcd[i]);
}
}
@@ -147,7 +147,7 @@ uart_cpu_acpi_probe(struct uart_class **classp, bus_space_tag_t *bst,
if (err != 0)
goto out;
- *classp = cd->clas;
+ *classp = cd->cd_class;
*rclk = 0;
*shiftp = 2;
*iowidthp = spcr->SerialPort.BitWidth / 8;
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 03792f8f65988..7f87b111f5026 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -26,6 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_acpi.h"
#include "opt_platform.h"
#include "opt_uart.h"
@@ -54,6 +55,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_dev_ns8250.h>
#include <dev/uart/uart_ppstypes.h>
+#ifdef DEV_ACPI
+#include <dev/uart/uart_cpu_acpi.h>
+#endif
#include <dev/ic/ns16550.h>
@@ -404,6 +408,26 @@ struct uart_class uart_ns8250_class = {
.uc_rshift = 0
};
+/*
+ * XXX -- refactor out ACPI and FDT ifdefs
+ */
+#ifdef DEV_ACPI
+static struct acpi_uart_compat_data acpi_compat_data[] = {
+ {"AMD0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
+ {"AMDI0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
+ {"PNP0500", &uart_ns8250_class, 0, 0, 0, 0, 0, "Standard PC COM port"},
+ {"PNP0501", &uart_ns8250_class, 0, 0, 0, 0, 0, "16550A-compatible COM port"},
+ {"PNP0502", &uart_ns8250_class, 0, 0, 0, 0, 0, "Multiport serial device (non-intelligent 16550)"},
+ {"PNP0510", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
+ {"PNP0511", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
+ {"WACF004", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen"},
+ {"WACF00E", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen 00e"},
+ {"FUJ02E5", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet at FuS Lifebook T"},
+ {NULL, NULL, 0, 0 , 0, 0, 0, NULL},
+};
+UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data);
+#endif
+
#ifdef FDT
static struct ofw_compat_data compat_data[] = {
{"ns16550", (uintptr_t)&uart_ns8250_class},
diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c
index 0b55b6a217dbf..08905d13c1e6d 100644
--- a/sys/dev/uart/uart_dev_pl011.c
+++ b/sys/dev/uart/uart_dev_pl011.c
@@ -342,9 +342,9 @@ UART_FDT_CLASS_AND_DEVICE(fdt_compat_data);
#ifdef DEV_ACPI
static struct acpi_uart_compat_data acpi_compat_data[] = {
- {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011},
- {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC},
- {NULL, NULL, 0},
+ {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011, 2, 0, 0, 0, "uart plo11"},
+ {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC, 2, 0, 0, 0, "uart plo11"},
+ {NULL, NULL, 0, 0, 0, 0, 0, NULL},
};
UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data);
#endif
diff --git a/sys/dev/uart/uart_dev_snps.c b/sys/dev/uart/uart_dev_snps.c
index 26696621c7d21..d8fc114824f84 100644
--- a/sys/dev/uart/uart_dev_snps.c
+++ b/sys/dev/uart/uart_dev_snps.c
@@ -99,22 +99,9 @@ early_putc_t *early_putc = uart_snps_early_putc;
#endif /* EARLY_PRINTF */
#endif
-static int
-snps_uart_attach(struct uart_softc *uart_sc)
-{
- struct snps_softc *sc;
-
- sc = (struct snps_softc *)uart_sc;
-
- /* UART requires to read USR reg when IIR_BUSY */
- uart_sc->sc_bas.busy_detect = 1;
-
- return (ns8250_bus_attach(uart_sc));
-}
-
static kobj_method_t snps_methods[] = {
KOBJMETHOD(uart_probe, ns8250_bus_probe),
- KOBJMETHOD(uart_attach, snps_uart_attach),
+ KOBJMETHOD(uart_attach, ns8250_bus_attach),
KOBJMETHOD(uart_detach, ns8250_bus_detach),
KOBJMETHOD(uart_flush, ns8250_bus_flush),
KOBJMETHOD(uart_getsig, ns8250_bus_getsig),
@@ -238,7 +225,7 @@ snps_probe(device_t dev)
if (bootverbose && clock == 0)
device_printf(dev, "could not determine frequency\n");
- error = uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0);
+ error = uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0, UART_F_BUSY_DETECT);
if (error != 0)
return (error);