From c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 7 Oct 2016 15:10:20 +0200 Subject: Update to FreeBSD head 2016-08-23 Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd. --- freebsd/sys/dev/led/led.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'freebsd/sys/dev/led/led.c') 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); -- cgit v1.2.3