aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/uart/uart_core.c
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2007-04-02 22:00:22 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2007-04-02 22:00:22 +0000
commitf8100ce2a70db5c60672578fee913d986ac1cf01 (patch)
treeb3ad51f3cb65c3badfb015aea4f71d800157abb8 /sys/dev/uart/uart_core.c
parent1bdb3fb97eb936148ebd3be52850c09ae7f72260 (diff)
downloadsrc-f8100ce2a70db5c60672578fee913d986ac1cf01.tar.gz
src-f8100ce2a70db5c60672578fee913d986ac1cf01.zip
Don't expose the uart_ops structure directly, but instead have
it obtained through the uart_class structure. This allows us to declare the uart_class structure as weak and as such allows us to reference it even when it's not compiled-in. It also allows is to get the uart_ops structure by name, which makes it possible to implement the dt tag handling in uart_getenv(). The side-effect of all this is that we're using the uart_class structure more consistently which means that we now also have access to the size of the bus space block needed by the hardware when we map the bus space, eliminating any hardcoding.
Notes
Notes: svn path=/head/; revision=168281
Diffstat (limited to 'sys/dev/uart/uart_core.c')
-rw-r--r--sys/dev/uart/uart_core.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c
index 6daf938c0482..f99127881e82 100644
--- a/sys/dev/uart/uart_core.c
+++ b/sys/dev/uart/uart_core.c
@@ -70,6 +70,24 @@ uart_add_sysdev(struct uart_devinfo *di)
SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
}
+const char *
+uart_getname(struct uart_class *uc)
+{
+ return ((uc != NULL) ? uc->name : NULL);
+}
+
+struct uart_ops *
+uart_getops(struct uart_class *uc)
+{
+ return ((uc != NULL) ? uc->uc_ops : NULL);
+}
+
+int
+uart_getrange(struct uart_class *uc)
+{
+ return ((uc != NULL) ? uc->uc_range : 0);
+}
+
/*
* Schedule a soft interrupt. We do this on the 0 to !0 transition
* of the TTY pending interrupt status.
@@ -293,6 +311,15 @@ uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan)
struct uart_devinfo *sysdev;
int error;
+ sc = device_get_softc(dev);
+
+ /*
+ * All uart_class references are weak. Check that the needed
+ * class has been compiled-in. Fail if not.
+ */
+ if (sc->sc_class == NULL)
+ return (ENXIO);
+
/*
* Initialize the instance. Note that the instance (=softc) does
* not necessarily match the hardware specific softc. We can't do
@@ -300,11 +327,10 @@ uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan)
* Hardware drivers cannot use any of the class specific fields
* while probing.
*/
- sc = device_get_softc(dev);
kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class);
sc->sc_dev = dev;
if (device_get_desc(dev) == NULL)
- device_set_desc(dev, sc->sc_class->name);
+ device_set_desc(dev, uart_getname(sc->sc_class));
/*
* Allocate the register resource. We assume that all UARTs have
@@ -316,12 +342,13 @@ uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan)
sc->sc_rrid = rid;
sc->sc_rtype = SYS_RES_IOPORT;
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
- 0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+ 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
if (sc->sc_rres == NULL) {
sc->sc_rrid = rid;
sc->sc_rtype = SYS_RES_MEMORY;
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
- &sc->sc_rrid, 0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+ &sc->sc_rrid, 0, ~0, uart_getrange(sc->sc_class),
+ RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
}
@@ -390,7 +417,7 @@ uart_bus_attach(device_t dev)
* collected by uart_bus_probe() intact.
*/
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
- 0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
+ 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
if (sc->sc_rres == NULL) {
mtx_destroy(&sc->sc_hwmtx_s);
return (ENXIO);