aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/gpio
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2019-12-09 19:00:39 +0000
committerIan Lepore <ian@FreeBSD.org>2019-12-09 19:00:39 +0000
commit989da27e45020e15bc0d43f4a39533211834e472 (patch)
tree4d0dac8e7f26c6799010be02450a1d61a022590f /sys/dev/gpio
parent2486d00026666397c4f9b42187af6ecf9765bf4b (diff)
Notes
Diffstat (limited to 'sys/dev/gpio')
-rw-r--r--sys/dev/gpio/gpioths.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/sys/dev/gpio/gpioths.c b/sys/dev/gpio/gpioths.c
index 0a4a0f3cb472..78c80c289375 100644
--- a/sys/dev/gpio/gpioths.c
+++ b/sys/dev/gpio/gpioths.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <dev/gpio/gpiobusvar.h>
@@ -90,7 +91,8 @@ struct gpioths_softc {
int temp;
int hum;
int fails;
- struct callout callout;
+ struct timeout_task task;
+ bool detaching;
};
static int
@@ -148,7 +150,7 @@ gpioths_dht_initread(struct gpioths_softc *sc)
*/
gpio_pin_setflags(sc->pin, GPIO_PIN_OUTPUT);
gpio_pin_set_active(sc->pin, false);
- DELAY(GPIOTHS_DHT_STARTCYCLE);
+ pause_sbt("gpioths", ustosbt(GPIOTHS_DHT_STARTCYCLE), C_PREL(2), 0);
gpio_pin_set_active(sc->pin, true);
gpio_pin_setflags(sc->pin, GPIO_PIN_INPUT);
}
@@ -285,14 +287,16 @@ error:
}
static void
-gpioths_poll(void *arg)
+gpioths_poll(void *arg, int pending __unused)
{
struct gpioths_softc *sc;
sc = (struct gpioths_softc *)arg;
gpioths_dht_readbytes(sc);
- callout_schedule(&sc->callout, GPIOTHS_POLLTIME * hz);
+ if (!sc->detaching)
+ taskqueue_enqueue_timeout_sbt(taskqueue_thread, &sc->task,
+ GPIOTHS_POLLTIME * SBT_1S, 0, C_PREL(3));
}
static int
@@ -309,6 +313,8 @@ gpioths_attach(device_t dev)
sc->dev = dev;
+ TIMEOUT_TASK_INIT(taskqueue_thread, &sc->task, 0, gpioths_poll, sc);
+
#ifdef FDT
/* Try to configure our pin from fdt data on fdt-based systems. */
err = gpio_pin_get_by_ofw_idx(dev, ofw_bus_get_node(dev), PIN_IDX,
@@ -355,9 +361,11 @@ gpioths_attach(device_t dev)
/*
* Do an initial read so we have correct values for reporting before
- * registering the sysctls that can access those values.
+ * registering the sysctls that can access those values. This also
+ * schedules the periodic polling the driver does every few seconds to
+ * update the sysctl variables.
*/
- gpioths_dht_readbytes(sc);
+ gpioths_poll(sc, 0);
sysctl_add_oid(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "temperature", \
CTLFLAG_RD | CTLTYPE_INT | CTLFLAG_MPSAFE,
@@ -370,9 +378,6 @@ gpioths_attach(device_t dev)
CTLFLAG_RD, &sc->fails, 0,
"failures since last successful read");
- callout_init(&sc->callout, 1);
- callout_reset(&sc->callout, GPIOTHS_POLLTIME * hz, gpioths_poll, sc);
-
return (0);
}
@@ -383,7 +388,9 @@ gpioths_detach(device_t dev)
sc = device_get_softc(dev);
gpio_pin_release(sc->pin);
- callout_drain(&sc->callout);
+ sc->detaching = true;
+ while (taskqueue_cancel_timeout(taskqueue_thread, &sc->task, NULL) != 0)
+ taskqueue_drain_timeout(taskqueue_thread, &sc->task);
return (0);
}