Simplify SME usage within acpibat:
* No need for sme_refresh callback; GPE handler will tell us when the device status changed (otherwise we can refresh data up to once a second, and that can take time!) * Since sme_refresh callback is gone, mutex is no longer required to synchronize GPE handlers and refresh thread, so nuke it. * Don't do any more work in GPE handler than required; use AcpiOsExecute to clear battery status/information in the sysmon_task_queue along with the refresh. With these changes running GNOME's battstat-applet-2 no longer causes my mouse to stutter once a second, and significantly reduces its CPU usage.
This commit is contained in:
parent
480fc38f3c
commit
daaa85a781
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: acpi_bat.c,v 1.66 2008/04/28 20:23:47 martin Exp $ */
|
||||
/* $NetBSD: acpi_bat.c,v 1.67 2008/06/03 01:11:18 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
@ -79,7 +79,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.66 2008/04/28 20:23:47 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.67 2008/06/03 01:11:18 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -115,9 +115,6 @@ struct acpibat_softc {
|
||||
|
||||
struct sysmon_envsys *sc_sme;
|
||||
envsys_data_t sc_sensor[ACPIBAT_NSENSORS];
|
||||
kmutex_t sc_mtx;
|
||||
|
||||
struct timeval sc_lastupdate, sc_updateinterval;
|
||||
};
|
||||
|
||||
static const char * const bat_hid[] = {
|
||||
@ -179,10 +176,11 @@ static ACPI_STATUS acpibat_get_info(device_t);
|
||||
static void acpibat_print_info(device_t);
|
||||
static void acpibat_print_stat(device_t);
|
||||
static void acpibat_update(void *);
|
||||
static void acpibat_update_info(void *);
|
||||
static void acpibat_update_stat(void *);
|
||||
|
||||
static void acpibat_init_envsys(device_t);
|
||||
static void acpibat_notify_handler(ACPI_HANDLE, UINT32, void *);
|
||||
static void acpibat_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
/*
|
||||
* acpibat_match:
|
||||
@ -216,7 +214,6 @@ acpibat_attach(device_t parent, device_t self, void *aux)
|
||||
aprint_normal(": ACPI Battery (Control Method)\n");
|
||||
|
||||
sc->sc_node = aa->aa_node;
|
||||
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
|
||||
rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle,
|
||||
ACPI_ALL_NOTIFY,
|
||||
@ -300,7 +297,6 @@ acpibat_battery_present(device_t dv)
|
||||
|
||||
sta = (uint32_t)val;
|
||||
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
sc->sc_available = ABAT_ALV_PRESENCE;
|
||||
if (sta & ACPIBAT_STA_PRESENT) {
|
||||
ABAT_SET(sc, ABAT_F_PRESENT);
|
||||
@ -309,8 +305,6 @@ acpibat_battery_present(device_t dv)
|
||||
} else
|
||||
sc->sc_sensor[ACPIBAT_PRESENT].value_cur = 0;
|
||||
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
|
||||
return (sta & ACPIBAT_STA_PRESENT) ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -348,7 +342,6 @@ acpibat_get_info(device_t dv)
|
||||
}
|
||||
p2 = p1->Package.Elements;
|
||||
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
if ((p2[0].Integer.Value & ACPIBAT_PWRUNIT_MA) != 0) {
|
||||
ABAT_SET(sc, ABAT_F_PWRUNIT_MA);
|
||||
capunit = ENVSYS_SAMPHOUR;
|
||||
@ -388,8 +381,6 @@ acpibat_get_info(device_t dv)
|
||||
(ENVSYS_FPERCENT|ENVSYS_FVALID_MAX);
|
||||
sc->sc_available = ABAT_ALV_INFO;
|
||||
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
|
||||
aprint_verbose_dev(dv, "battery info: %s, %s, %s",
|
||||
p2[12].String.Pointer, p2[11].String.Pointer, p2[9].String.Pointer);
|
||||
if (p2[10].String.Pointer)
|
||||
@ -440,8 +431,6 @@ acpibat_get_status(device_t dv)
|
||||
}
|
||||
p2 = p1->Package.Elements;
|
||||
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
|
||||
status = p2[0].Integer.Value;
|
||||
battrate = p2[1].Integer.Value;
|
||||
|
||||
@ -494,8 +483,6 @@ acpibat_get_status(device_t dv)
|
||||
ENVSYS_BATTERY_CAPACITY_CRITICAL;
|
||||
}
|
||||
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
|
||||
rv = AE_OK;
|
||||
|
||||
out:
|
||||
@ -619,6 +606,26 @@ acpibat_update(void *arg)
|
||||
acpibat_print_stat(dv);
|
||||
}
|
||||
|
||||
static void
|
||||
acpibat_update_info(void *arg)
|
||||
{
|
||||
device_t dev = arg;
|
||||
struct acpibat_softc *sc = device_private(dev);
|
||||
|
||||
acpibat_clear_presence(sc);
|
||||
acpibat_update(arg);
|
||||
}
|
||||
|
||||
static void
|
||||
acpibat_update_stat(void *arg)
|
||||
{
|
||||
device_t dev = arg;
|
||||
struct acpibat_softc *sc = device_private(dev);
|
||||
|
||||
acpibat_clear_stat(sc);
|
||||
acpibat_update(arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* acpibat_notify_handler:
|
||||
*
|
||||
@ -628,7 +635,6 @@ static void
|
||||
acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
||||
{
|
||||
device_t dv = context;
|
||||
struct acpibat_softc *sc = device_private(dv);
|
||||
int rv;
|
||||
|
||||
#ifdef ACPI_BAT_DEBUG
|
||||
@ -641,10 +647,7 @@ acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
||||
|
||||
case ACPI_NOTIFY_DeviceCheck:
|
||||
case ACPI_NOTIFY_BatteryInformationChanged:
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
acpibat_clear_presence(sc);
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update, dv);
|
||||
rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update_info, dv);
|
||||
if (ACPI_FAILURE(rv))
|
||||
aprint_error_dev(dv,
|
||||
"unable to queue status check: %s\n",
|
||||
@ -652,10 +655,7 @@ acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_BatteryStatusChanged:
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
acpibat_clear_stat(sc);
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update, dv);
|
||||
rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update_stat, dv);
|
||||
if (ACPI_FAILURE(rv))
|
||||
aprint_error_dev(dv,
|
||||
"unable to queue status check: %s\n",
|
||||
@ -730,26 +730,14 @@ acpibat_init_envsys(device_t dv)
|
||||
}
|
||||
|
||||
sc->sc_sme->sme_name = device_xname(dv);
|
||||
sc->sc_sme->sme_cookie = dv;
|
||||
sc->sc_sme->sme_refresh = acpibat_refresh;
|
||||
sc->sc_sme->sme_refresh = NULL;
|
||||
sc->sc_sme->sme_class = SME_CLASS_BATTERY;
|
||||
sc->sc_sme->sme_flags = SME_INIT_REFRESH;
|
||||
sc->sc_sme->sme_flags = SME_DISABLE_REFRESH;
|
||||
|
||||
sc->sc_updateinterval.tv_sec = 1;
|
||||
sc->sc_updateinterval.tv_usec = 0;
|
||||
acpibat_update(dv);
|
||||
|
||||
if (sysmon_envsys_register(sc->sc_sme)) {
|
||||
aprint_error_dev(dv, "unable to register with sysmon\n");
|
||||
sysmon_envsys_destroy(sc->sc_sme);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acpibat_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
device_t dv = sme->sme_cookie;
|
||||
struct acpibat_softc *sc = device_private(dv);
|
||||
|
||||
if (ratecheck(&sc->sc_lastupdate, &sc->sc_updateinterval))
|
||||
acpibat_update(dv);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user