summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/led
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-10-07 15:10:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:31 +0100
commitc40e45b75eb76d79a05c7fa85c1fa9b5c728a12f (patch)
treead4f2519067709f00ab98b3c591186c26dc3a21f /freebsd/sys/dev/led
parentuserspace-header-gen.py: Simplify program ports (diff)
downloadrtems-libbsd-c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f.tar.bz2
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
Diffstat (limited to 'freebsd/sys/dev/led')
-rw-r--r--freebsd/sys/dev/led/led.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/freebsd/sys/dev/led/led.c b/freebsd/sys/dev/led/led.c
index 1b01132f..87cf9993 100644
--- a/freebsd/sys/dev/led/led.c
+++ b/freebsd/sys/dev/led/led.c
@@ -45,6 +45,7 @@ static struct mtx led_mtx;
static struct sx led_sx;
static LIST_HEAD(, ledsc) led_list = LIST_HEAD_INITIALIZER(led_list);
static struct callout led_ch;
+static int blinkers = 0;
static MALLOC_DEFINE(M_LED, "LED", "LED driver");
@@ -53,7 +54,6 @@ led_timeout(void *p)
{
struct ledsc *sc;
- mtx_lock(&led_mtx);
LIST_FOREACH(sc, &led_list, list) {
if (sc->ptr == NULL)
continue;
@@ -63,6 +63,7 @@ led_timeout(void *p)
}
if (*sc->ptr == '.') {
sc->ptr = NULL;
+ blinkers--;
continue;
} else if (*sc->ptr == 'U' || *sc->ptr == 'u') {
if (sc->last_second == time_second)
@@ -80,9 +81,8 @@ led_timeout(void *p)
if (*sc->ptr == '\0')
sc->ptr = sc->str;
}
- mtx_unlock(&led_mtx);
- callout_reset(&led_ch, hz / 10, led_timeout, p);
- return;
+ if (blinkers > 0)
+ callout_reset(&led_ch, hz / 10, led_timeout, p);
}
static int
@@ -94,9 +94,15 @@ led_state(struct ledsc *sc, struct sbuf **sb, int state)
sc->spec = *sb;
if (*sb != NULL) {
sc->str = sbuf_data(*sb);
+ if (sc->ptr == NULL) {
+ blinkers++;
+ callout_reset(&led_ch, hz / 10, led_timeout, NULL);
+ }
sc->ptr = sc->str;
} else {
sc->str = NULL;
+ if (sc->ptr != NULL)
+ blinkers--;
sc->ptr = NULL;
sc->func(sc->private, state);
}
@@ -288,10 +294,9 @@ led_create_state(led_t *func, void *priv, char const *name, int state)
mtx_lock(&led_mtx);
sc->dev->si_drv1 = sc;
- if (LIST_EMPTY(&led_list))
- callout_reset(&led_ch, hz / 10, led_timeout, NULL);
LIST_INSERT_HEAD(&led_list, sc, list);
- sc->func(sc->private, state != 0);
+ if (state != -1)
+ sc->func(sc->private, state != 0);
mtx_unlock(&led_mtx);
return (sc->dev);
@@ -305,7 +310,8 @@ led_destroy(struct cdev *dev)
mtx_lock(&led_mtx);
sc = dev->si_drv1;
dev->si_drv1 = NULL;
-
+ if (sc->ptr != NULL)
+ blinkers--;
LIST_REMOVE(sc, list);
if (LIST_EMPTY(&led_list))
callout_stop(&led_ch);
@@ -328,7 +334,7 @@ led_drvinit(void *unused)
led_unit = new_unrhdr(0, INT_MAX, NULL);
mtx_init(&led_mtx, "LED mtx", NULL, MTX_DEF);
sx_init(&led_sx, "LED sx");
- callout_init(&led_ch, CALLOUT_MPSAFE);
+ callout_init_mtx(&led_ch, &led_mtx, 0);
}
SYSINIT(leddev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, led_drvinit, NULL);