diff options
author | markus <markus@FreeBSD.org> | 2005-08-04 22:48:36 +0000 |
---|---|---|
committer | markus <markus@FreeBSD.org> | 2005-08-04 22:48:36 +0000 |
commit | cf76314de35779e98b3beef3d947a013553b9d45 (patch) | |
tree | 4f9c6a1e5fe1a3fc9405f94a3d15f2fc5209e11d /sys/dev/acpi_support | |
parent | 94bbef20db67aace419af23498e98f7d8f426de7 (diff) | |
download | FreeBSD-src-cf76314de35779e98b3beef3d947a013553b9d45.zip FreeBSD-src-cf76314de35779e98b3beef3d947a013553b9d45.tar.gz |
Don't lock when holding led_mtx, instead use AcpiOsQueueForExecution to defer
the locking.
Idea taken from: acpi_asus(4)
Approved by: philip
Reported by: avatar
Gordon Bergling <gbergling@0xfce3.net>
MFC after: 1 week
Diffstat (limited to 'sys/dev/acpi_support')
-rw-r--r-- | sys/dev/acpi_support/acpi_ibm.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c index 8dcf8a3..a7f4d0f 100644 --- a/sys/dev/acpi_support/acpi_ibm.c +++ b/sys/dev/acpi_support/acpi_ibm.c @@ -144,7 +144,11 @@ struct acpi_ibm_softc { int light_val; int light_get_supported; int light_set_supported; + + /* led(4) interface */ struct cdev *led_dev; + int led_busy; + int led_state; int wlan_bt_flags; int thermal_updt_supported; @@ -240,6 +244,9 @@ static int acpi_ibm_probe(device_t dev); static int acpi_ibm_attach(device_t dev); static int acpi_ibm_detach(device_t dev); +static void ibm_led(void *softc, int onoff); +static void ibm_led_task(struct acpi_ibm_softc *sc, int pending __unused); + static int acpi_ibm_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int method); static int acpi_ibm_sysctl_get(struct acpi_ibm_softc *sc, int method); @@ -274,10 +281,30 @@ static char *ibm_ids[] = {"IBM0057", "IBM0068", NULL}; static void ibm_led(void *softc, int onoff) { + struct acpi_ibm_softc* sc = (struct acpi_ibm_softc*) softc; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + if (sc->led_busy) + return; + + sc->led_busy = 1; + sc->led_state = onoff; + + AcpiOsQueueForExecution(OSD_PRIORITY_LO, + (void *)ibm_led_task, sc); +} + +static void +ibm_led_task(struct acpi_ibm_softc *sc, int pending __unused) +{ + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_BEGIN(ibm); - acpi_ibm_sysctl_set((struct acpi_ibm_softc*)softc, - ACPI_IBM_METHOD_THINKLIGHT, onoff); + acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_THINKLIGHT, sc->led_state); ACPI_SERIAL_END(ibm); + + sc->led_busy = 0; } static int |