svn commit: r244241 - projects/calloutng/sys/dev/led
Alexander Motin
mav at FreeBSD.org
Sat Dec 15 07:11:17 UTC 2012
Author: mav
Date: Sat Dec 15 07:11:16 2012
New Revision: 244241
URL: http://svnweb.freebsd.org/changeset/base/244241
Log:
Make led(4) fire callouts at 10Hz only when there is at least one LED that
is requested to blink. Do not fire if all LEDs are static (usual case).
Modified:
projects/calloutng/sys/dev/led/led.c
Modified: projects/calloutng/sys/dev/led/led.c
==============================================================================
--- projects/calloutng/sys/dev/led/led.c Sat Dec 15 02:04:46 2012 (r244240)
+++ projects/calloutng/sys/dev/led/led.c Sat Dec 15 07:11:16 2012 (r244241)
@@ -43,6 +43,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");
@@ -51,7 +52,6 @@ led_timeout(void *p)
{
struct ledsc *sc;
- mtx_lock(&led_mtx);
LIST_FOREACH(sc, &led_list, list) {
if (sc->ptr == NULL)
continue;
@@ -61,6 +61,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)
@@ -78,9 +79,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
@@ -92,9 +92,15 @@ led_state(struct ledsc *sc, struct sbuf
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);
}
@@ -286,8 +292,6 @@ led_create_state(led_t *func, void *priv
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);
mtx_unlock(&led_mtx);
@@ -303,7 +307,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);
@@ -326,7 +331,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);
More information about the svn-src-projects
mailing list