diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-09-13 17:14:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-09-13 17:14:55 +0000 |
commit | 13ce016f5c8aa37ba60bda17252574c309e16b5f (patch) | |
tree | 19ab29272f7067d61a5d27c66aad84f77778c31a /sys | |
parent | 0ffa80da02848060615dd66946a91b3d27dd6ec0 (diff) |
Split out the code that collects data from acpiac(4), acpibat(4) and
acpisbs(4) for apm(4) and hook it up to the arm64 version of apm(4) on
systems with ACPI.
ok kn@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/arm64/acpi_machdep.c | 9 | ||||
-rw-r--r-- | sys/dev/acpi/acpi.c | 201 | ||||
-rw-r--r-- | sys/dev/acpi/acpivar.h | 5 |
3 files changed, 116 insertions, 99 deletions
diff --git a/sys/arch/arm64/arm64/acpi_machdep.c b/sys/arch/arm64/arm64/acpi_machdep.c index 97377d11654..abcdfe70b12 100644 --- a/sys/arch/arm64/arm64/acpi_machdep.c +++ b/sys/arch/arm64/arm64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.19 2022/02/09 23:54:55 deraadt Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.20 2022/09/13 17:14:54 kettenis Exp $ */ /* * Copyright (c) 2018 Mark Kettenis * @@ -22,6 +22,7 @@ #include <uvm/uvm_extern.h> +#include <machine/apmvar.h> #include <machine/bus.h> #include <machine/fdt.h> @@ -33,6 +34,8 @@ #include <arm64/dev/acpiiort.h> +#include "apm.h" + int lid_action; int pwr_action = 1; @@ -134,7 +137,9 @@ acpi_release_glk(uint32_t *lock) void acpi_attach_machdep(struct acpi_softc *sc) { - /* Nothing to do. */ +#if NAPM > 0 + apm_setinfohook(acpi_apminfo); +#endif } void * diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index bef27d893c9..fc3c1d160ee 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.417 2022/09/12 17:42:31 kettenis Exp $ */ +/* $OpenBSD: acpi.c,v 1.418 2022/09/13 17:14:54 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -3244,6 +3244,109 @@ acpi_foundsbs(struct aml_node *node, void *arg) } int +acpi_apminfo(struct apm_power_info *pi) +{ + struct acpi_softc *sc = acpi_softc; + struct acpi_ac *ac; + struct acpi_bat *bat; + struct acpi_sbs *sbs; + int bats; + unsigned int capacity, remaining, minutes, rate; + + /* A/C */ + pi->ac_state = APM_AC_UNKNOWN; +// XXX replace with new power code + SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { + if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) + pi->ac_state = APM_AC_ON; + else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) + if (pi->ac_state == APM_AC_UNKNOWN) + pi->ac_state = APM_AC_OFF; + } + + /* battery */ + pi->battery_state = APM_BATT_UNKNOWN; + pi->battery_life = 0; + pi->minutes_left = 0; + bats = 0; + capacity = 0; + remaining = 0; + minutes = 0; + rate = 0; + SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { + if (bat->aba_softc->sc_bat_present == 0) + continue; + + if (bat->aba_softc->sc_bix.bix_last_capacity == 0) + continue; + + bats++; + capacity += bat->aba_softc->sc_bix.bix_last_capacity; + remaining += min(bat->aba_softc->sc_bst.bst_capacity, + bat->aba_softc->sc_bix.bix_last_capacity); + + if (bat->aba_softc->sc_bst.bst_state & BST_CHARGE) + pi->battery_state = APM_BATT_CHARGING; + + if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) + continue; + else if (bat->aba_softc->sc_bst.bst_rate > 1) + rate = bat->aba_softc->sc_bst.bst_rate; + + minutes += bat->aba_softc->sc_bst.bst_capacity; + } + + SLIST_FOREACH(sbs, &sc->sc_sbs, asbs_link) { + if (sbs->asbs_softc->sc_batteries_present == 0) + continue; + + if (sbs->asbs_softc->sc_battery.rel_charge == 0) + continue; + + bats++; + capacity += 100; + remaining += min(100, + sbs->asbs_softc->sc_battery.rel_charge); + + if (sbs->asbs_softc->sc_battery.run_time == + ACPISBS_VALUE_UNKNOWN) + continue; + + rate = 60; /* XXX */ + minutes += sbs->asbs_softc->sc_battery.run_time; + } + + if (bats == 0) { + pi->battery_state = APM_BATTERY_ABSENT; + pi->battery_life = 0; + pi->minutes_left = (unsigned int)-1; + return 0; + } + + if (rate == 0) + pi->minutes_left = (unsigned int)-1; + else if (pi->battery_state == APM_BATT_CHARGING) + pi->minutes_left = 60 * (capacity - remaining) / rate; + else + pi->minutes_left = 60 * minutes / rate; + + pi->battery_life = remaining * 100 / capacity; + + if (pi->battery_state == APM_BATT_CHARGING) + return 0; + + /* running on battery */ + if (pi->battery_life > 50) + pi->battery_state = APM_BATT_HIGH; + else if (pi->battery_life > 25) + pi->battery_state = APM_BATT_LOW; + else + pi->battery_state = APM_BATT_CRITICAL; + + return 0; +} + +int acpiopen(dev_t dev, int flag, int mode, struct proc *p) { int error = 0; @@ -3314,12 +3417,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { int error = 0; struct acpi_softc *sc; - struct acpi_ac *ac; - struct acpi_bat *bat; - struct acpi_sbs *sbs; struct apm_power_info *pi = (struct apm_power_info *)data; - int bats; - unsigned int capacity, remaining, minutes, rate; int s; if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || @@ -3355,96 +3453,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; #endif case APM_IOC_GETPOWER: - /* A/C */ - pi->ac_state = APM_AC_UNKNOWN; -// XXX replace with new power code - SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { - if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) - pi->ac_state = APM_AC_ON; - else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) - if (pi->ac_state == APM_AC_UNKNOWN) - pi->ac_state = APM_AC_OFF; - } - - /* battery */ - pi->battery_state = APM_BATT_UNKNOWN; - pi->battery_life = 0; - pi->minutes_left = 0; - bats = 0; - capacity = 0; - remaining = 0; - minutes = 0; - rate = 0; - SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { - if (bat->aba_softc->sc_bat_present == 0) - continue; - - if (bat->aba_softc->sc_bix.bix_last_capacity == 0) - continue; - - bats++; - capacity += bat->aba_softc->sc_bix.bix_last_capacity; - remaining += min(bat->aba_softc->sc_bst.bst_capacity, - bat->aba_softc->sc_bix.bix_last_capacity); - - if (bat->aba_softc->sc_bst.bst_state & BST_CHARGE) - pi->battery_state = APM_BATT_CHARGING; - - if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) - continue; - else if (bat->aba_softc->sc_bst.bst_rate > 1) - rate = bat->aba_softc->sc_bst.bst_rate; - - minutes += bat->aba_softc->sc_bst.bst_capacity; - } - - SLIST_FOREACH(sbs, &sc->sc_sbs, asbs_link) { - if (sbs->asbs_softc->sc_batteries_present == 0) - continue; - - if (sbs->asbs_softc->sc_battery.rel_charge == 0) - continue; - - bats++; - capacity += 100; - remaining += min(100, - sbs->asbs_softc->sc_battery.rel_charge); - - if (sbs->asbs_softc->sc_battery.run_time == - ACPISBS_VALUE_UNKNOWN) - continue; - - rate = 60; /* XXX */ - minutes += sbs->asbs_softc->sc_battery.run_time; - } - - if (bats == 0) { - pi->battery_state = APM_BATTERY_ABSENT; - pi->battery_life = 0; - pi->minutes_left = (unsigned int)-1; - break; - } - - if (rate == 0) - pi->minutes_left = (unsigned int)-1; - else if (pi->battery_state == APM_BATT_CHARGING) - pi->minutes_left = 60 * (capacity - remaining) / rate; - else - pi->minutes_left = 60 * minutes / rate; - - pi->battery_life = remaining * 100 / capacity; - - if (pi->battery_state == APM_BATT_CHARGING) - break; - - /* running on battery */ - if (pi->battery_life > 50) - pi->battery_state = APM_BATT_HIGH; - else if (pi->battery_life > 25) - pi->battery_state = APM_BATT_LOW; - else - pi->battery_state = APM_BATT_CRITICAL; - + error = acpi_apminfo(pi); break; default: diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index 75f74d8a0cf..a9b4a2ae98a 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.121 2022/08/10 16:58:16 patrick Exp $ */ +/* $OpenBSD: acpivar.h,v 1.122 2022/09/13 17:14:54 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -384,6 +384,9 @@ void acpi_indicator(struct acpi_softc *, int); void acpi_disable_allgpes(struct acpi_softc *); void acpi_enable_wakegpes(struct acpi_softc *, int); +struct apm_power_info; +int acpi_apminfo(struct apm_power_info *); + int acpi_record_event(struct acpi_softc *, u_int); void acpi_addtask(struct acpi_softc *, void (*)(void *, int), void *, int); |