diff options
author | iwasaki <iwasaki@FreeBSD.org> | 2002-03-04 18:46:13 +0000 |
---|---|---|
committer | iwasaki <iwasaki@FreeBSD.org> | 2002-03-04 18:46:13 +0000 |
commit | 3f245d8dd193f05b337f1358ec6b33ed212f9cc1 (patch) | |
tree | 8012c8174b9cc8503bad897aec51d04ec2c4490b /sys | |
parent | 3fe10323bf98b7928a3f885f578ec703252ee6b7 (diff) | |
download | FreeBSD-src-3f245d8dd193f05b337f1358ec6b33ed212f9cc1.zip FreeBSD-src-3f245d8dd193f05b337f1358ec6b33ed212f9cc1.tar.gz |
Add generalized power profile code.
This makes other power-management system (APM for now) to be able to
generate power profile change events (ie. AC-line status changes), and
other kernel components, not only the ACPI components, can be notified
the events.
- move subroutines in acpi_powerprofile.c (removed) to kern/subr_power.c
- call power_profile_set_state() also from APM driver when AC-line
status changes
- add call-back function for Crusoe LongRun controlling on power
profile changes for a example
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/identcpu.c | 70 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_acad.c | 3 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 31 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_powerprofile.c | 65 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_thermal.c | 20 | ||||
-rw-r--r-- | sys/dev/acpica/acpivar.h | 15 | ||||
-rw-r--r-- | sys/i386/apm/apm.c | 20 | ||||
-rw-r--r-- | sys/i386/bios/apm.c | 20 | ||||
-rw-r--r-- | sys/i386/i386/identcpu.c | 70 | ||||
-rw-r--r-- | sys/kern/subr_power.c | 31 | ||||
-rw-r--r-- | sys/modules/acpi/Makefile | 2 | ||||
-rw-r--r-- | sys/sys/power.h | 14 |
13 files changed, 267 insertions, 95 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index 156d2c0..6aa0967 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -48,6 +48,7 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/power.h> #include <machine/asmacros.h> #include <machine/clock.h> @@ -1135,9 +1136,40 @@ static u_int crusoe_longrun; static u_int crusoe_frequency; static u_int crusoe_voltage; static u_int crusoe_percentage; +static u_int crusoe_performance_longrun = LONGRUN_MODE_PERFORMANCE; +static u_int crusoe_economy_longrun = LONGRUN_MODE_ECONOMY; static struct sysctl_ctx_list crusoe_sysctl_ctx; static struct sysctl_oid *crusoe_sysctl_tree; +static void +tmx86_longrun_power_profile(void *arg) +{ + int state; + u_int new; + + state = power_profile_get_state(); + if (state != POWER_PROFILE_PERFORMANCE && + state != POWER_PROFILE_ECONOMY) { + return; + } + + switch (state) { + case POWER_PROFILE_PERFORMANCE: + new =crusoe_performance_longrun; + break; + case POWER_PROFILE_ECONOMY: + new = crusoe_economy_longrun; + break; + default: + new = tmx86_get_longrun_mode(); + break; + } + + if (tmx86_get_longrun_mode() != new) { + tmx86_set_longrun_mode(new); + } +} + static int tmx86_longrun_sysctl(SYSCTL_HANDLER_ARGS) { @@ -1175,6 +1207,34 @@ tmx86_status_sysctl(SYSCTL_HANDLER_ARGS) return (error); } +static int +tmx86_longrun_profile_sysctl(SYSCTL_HANDLER_ARGS) +{ + u_int32_t *argp; + u_int32_t arg; + int error; + + argp = (u_int32_t *)oidp->oid_arg1; + arg = *argp; + error = sysctl_handle_int(oidp, &arg, 0, req); + + /* error or no new value */ + if ((error != 0) || (req->newptr == NULL)) + return (error); + + /* range check */ + if (arg >= LONGRUN_MODE_UNKNOWN) + return (EINVAL); + + /* set new value and possibly switch */ + *argp = arg; + + tmx86_longrun_power_profile(NULL); + + return (0); + +} + static void setup_tmx86_longrun(void) { @@ -1205,6 +1265,16 @@ setup_tmx86_longrun(void) OID_AUTO, "percentage", CTLTYPE_INT | CTLFLAG_RD, &crusoe_percentage, 0, tmx86_status_sysctl, "I", "Processing performance (%)"); + SYSCTL_ADD_PROC(&crusoe_sysctl_ctx, SYSCTL_CHILDREN(crusoe_sysctl_tree), + OID_AUTO, "performance_longrun", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_RW, + &crusoe_performance_longrun, 0, tmx86_longrun_profile_sysctl, "I", ""); + SYSCTL_ADD_PROC(&crusoe_sysctl_ctx, SYSCTL_CHILDREN(crusoe_sysctl_tree), + OID_AUTO, "economy_longrun", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_RW, + &crusoe_economy_longrun, 0, tmx86_longrun_profile_sysctl, "I", ""); + + /* register performance profile change handler */ + EVENTHANDLER_REGISTER(power_profile_change, tmx86_longrun_power_profile, NULL, 0); + } static void diff --git a/sys/conf/files b/sys/conf/files index 554821b..03ebaca 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -207,7 +207,6 @@ dev/acpica/acpi_ec.c optional acpica dev/acpica/acpi_lid.c optional acpica dev/acpica/acpi_pcib.c optional acpica pci dev/acpica/acpi_powerres.c optional acpica nowerror -dev/acpica/acpi_powerprofile.c optional acpica dev/acpica/acpi_resource.c optional acpica dev/acpica/acpi_thermal.c optional acpica dev/acpica/acpi_timer.c optional acpica diff --git a/sys/dev/acpica/acpi_acad.c b/sys/dev/acpica/acpi_acad.c index 10fe39a..2c9daf9 100644 --- a/sys/dev/acpica/acpi_acad.c +++ b/sys/dev/acpica/acpi_acad.c @@ -37,6 +37,7 @@ #include <sys/ioccom.h> #include <sys/malloc.h> #include <sys/conf.h> +#include <sys/power.h> #include "acpi.h" #include <dev/acpica/acpivar.h> @@ -79,7 +80,7 @@ acpi_acad_get_status(void *context) if (sc->status != newstatus) { sc->status = newstatus; /* set system power profile based on AC adapter status */ - powerprofile_set_state(sc->status ? POWERPROFILE_PERFORMANCE : POWERPROFILE_ECONOMY); + power_profile_set_state(sc->status ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY); ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "%s Line\n",(sc->status) ? "On" : "Off"); } diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index ab55023..7014705 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/kernel.h> #include <sys/bus.h> +#include <sys/power.h> #include <machine/bus_pio.h> #include <machine/bus.h> @@ -99,7 +100,7 @@ static int acpi_cpu_probe(device_t dev); static int acpi_cpu_attach(device_t dev); static void acpi_cpu_init_throttling(void *arg); static void acpi_cpu_set_speed(u_int32_t speed); -static void acpi_cpu_powerprofile(void *arg); +static void acpi_cpu_power_profile(void *arg); static int acpi_cpu_speed_sysctl(SYSCTL_HANDLER_ARGS); static device_method_t acpi_cpu_methods[] = { @@ -280,7 +281,7 @@ acpi_cpu_init_throttling(void *arg) cpu_economy_state = cpu_temp_speed; /* register performance profile change handler */ - EVENTHANDLER_REGISTER(powerprofile_change, acpi_cpu_powerprofile, NULL, 0); + EVENTHANDLER_REGISTER(power_profile_change, acpi_cpu_power_profile, NULL, 0); /* if ACPI 2.0+, signal platform that we are taking over throttling */ if (cpu_pstate_cnt != 0) { @@ -291,7 +292,7 @@ acpi_cpu_init_throttling(void *arg) ACPI_UNLOCK; /* set initial speed */ - acpi_cpu_powerprofile(NULL); + acpi_cpu_power_profile(NULL); printf("acpi_cpu: CPU throttling enabled, %d steps from 100%% to %d.%d%%\n", CPU_MAX_SPEED, CPU_SPEED_PRINTABLE(1)); @@ -347,13 +348,31 @@ acpi_cpu_set_speed(u_int32_t speed) * Uses the ACPI lock to avoid reentrancy. */ static void -acpi_cpu_powerprofile(void *arg) +acpi_cpu_power_profile(void *arg) { + int state; u_int32_t new; + state = power_profile_get_state(); + if (state != POWER_PROFILE_PERFORMANCE && + state != POWER_PROFILE_ECONOMY) { + return; + } + ACPI_LOCK; - new = (powerprofile_get_state() == POWERPROFILE_PERFORMANCE) ? cpu_performance_state : cpu_economy_state; + switch (state) { + case POWER_PROFILE_PERFORMANCE: + new = cpu_performance_state; + break; + case POWER_PROFILE_ECONOMY: + new = cpu_economy_state; + break; + default: + new = cpu_current_state; + break; + } + if (cpu_current_state != new) acpi_cpu_set_speed(new); @@ -387,7 +406,7 @@ acpi_cpu_speed_sysctl(SYSCTL_HANDLER_ARGS) /* set new value and possibly switch */ *argp = arg; - acpi_cpu_powerprofile(NULL); + acpi_cpu_power_profile(NULL); return(0); } diff --git a/sys/dev/acpica/acpi_powerprofile.c b/sys/dev/acpica/acpi_powerprofile.c deleted file mode 100644 index d5d952c..0000000 --- a/sys/dev/acpica/acpi_powerprofile.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2001 Michael Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "opt_acpi.h" /* XXX trim includes */ -#include <sys/param.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include "acpi.h" - -#include <dev/acpica/acpivar.h> - -static int powerprofile_state = POWERPROFILE_PERFORMANCE; - -int -powerprofile_get_state(void) -{ - return(powerprofile_state); -} - -void -powerprofile_set_state(int state) -{ - int changed; - - ACPI_LOCK; - if (state != powerprofile_state) { - powerprofile_state = state; - changed = 1; - printf("system power profile changed to '%s'\n", - (state == POWERPROFILE_PERFORMANCE) ? "performance" : "economy"); - } else { - changed = 0; - } - ACPI_UNLOCK; - if (changed) - EVENTHANDLER_INVOKE(powerprofile_change); -} - diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c index 92902af..15acc1d 100644 --- a/sys/dev/acpica/acpi_thermal.c +++ b/sys/dev/acpica/acpi_thermal.c @@ -38,6 +38,7 @@ #include <sys/reboot.h> #include <sys/sysctl.h> #include <sys/unistd.h> +#include <sys/power.h> #include "acpi.h" @@ -87,7 +88,7 @@ struct acpi_tz_softc { #define TZ_THFLAG_CRT (1<<3) int tz_flags; #define TZ_FLAG_NO_SCP (1<<0) /* no _SCP method */ -#define TZ_FLAG_GETPROFILE (1<<1) /* fetch powerprofile in timeout */ +#define TZ_FLAG_GETPROFILE (1<<1) /* fetch power_profile in timeout */ struct timespec tz_cooling_started; /* current cooling starting time */ struct sysctl_ctx_list tz_sysctl_ctx; /* sysctl tree */ @@ -109,7 +110,7 @@ static void acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what); static int acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS); static void acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context); static void acpi_tz_timeout(struct acpi_tz_softc *sc); -static void acpi_tz_powerprofile(void *arg); +static void acpi_tz_power_profile(void *arg); static void acpi_tz_thread(void *arg); static struct proc *acpi_tz_proc; @@ -248,7 +249,7 @@ acpi_tz_attach(device_t dev) * invocation by our timeout. We defer it like this so that the rest * of the subsystem has time to come up. */ - EVENTHANDLER_REGISTER(powerprofile_change, acpi_tz_powerprofile, sc, 0); + EVENTHANDLER_REGISTER(power_profile_change, acpi_tz_power_profile, sc, 0); sc->tz_flags |= TZ_FLAG_GETPROFILE; /* @@ -713,7 +714,7 @@ acpi_tz_timeout(struct acpi_tz_softc *sc) /* do we need to get the power profile settings? */ if (sc->tz_flags & TZ_FLAG_GETPROFILE) { - acpi_tz_powerprofile((void *)sc); + acpi_tz_power_profile((void *)sc); sc->tz_flags &= ~TZ_FLAG_GETPROFILE; } @@ -733,12 +734,19 @@ acpi_tz_timeout(struct acpi_tz_softc *sc) * to get the ACPI lock itself. */ static void -acpi_tz_powerprofile(void *arg) +acpi_tz_power_profile(void *arg) { ACPI_OBJECT_LIST args; ACPI_OBJECT obj; ACPI_STATUS status; struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; + int state; + + state = power_profile_get_state(); + if (state != POWER_PROFILE_PERFORMANCE && + state != POWER_PROFILE_ECONOMY) { + return; + } ACPI_LOCK; @@ -747,7 +755,7 @@ acpi_tz_powerprofile(void *arg) /* call _SCP to set the new profile */ obj.Type = ACPI_TYPE_INTEGER; - obj.Integer.Value = (powerprofile_get_state() == POWERPROFILE_PERFORMANCE) ? 0 : 1; + obj.Integer.Value = (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1; args.Count = 1; args.Pointer = &obj; if (ACPI_FAILURE(status = AcpiEvaluateObject(sc->tz_handle, "_SCP", &args, NULL))) { diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index ac86c41..5a04cf5 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -358,21 +358,6 @@ extern int acpi_cmbat_get_battinfo(int, struct acpi_battinfo *); extern int acpi_acad_get_acline(int *); -/* - * System power API. - * - * XXX should this be further generalised? - * - */ -#define POWERPROFILE_PERFORMANCE 0 -#define POWERPROFILE_ECONOMY 1 - -extern int powerprofile_get_state(void); -extern void powerprofile_set_state(int state); - -typedef void (*powerprofile_change_hook)(void *); -EVENTHANDLER_DECLARE(powerprofile_change, powerprofile_change_hook); - #if defined(ACPI_MAX_THREADS) && ACPI_MAX_THREADS > 0 /* * ACPI task kernel thread initialization. diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c index 85d4bd2..9749e0c 100644 --- a/sys/i386/apm/apm.c +++ b/sys/i386/apm/apm.c @@ -906,6 +906,24 @@ apm_record_event(struct apm_softc *sc, u_int event_type) return (sc->sc_flags & SCFLAG_OCTL) ? 0 : 1; /* user may handle */ } +/* Power profile */ +static void +apm_power_profile(struct apm_softc *sc) +{ + int state; + struct apm_info info; + static int apm_acline = 0; + + if (apm_get_info(&info)) + return; + + if (apm_acline != info.ai_acline) { + apm_acline = info.ai_acline; + state = apm_acline ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY; + power_profile_set_state(state); + } +} + /* Process APM event */ static void apm_processevent(void) @@ -975,6 +993,7 @@ apm_processevent(void) break; OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME); apm_record_event(sc, apm_event); @@ -982,6 +1001,7 @@ apm_processevent(void) break; OPMEV_DEBUGMESSAGE(PMEV_CAPABILITIESCHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; case PMEV_NOEVENT: break; diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c index 85d4bd2..9749e0c 100644 --- a/sys/i386/bios/apm.c +++ b/sys/i386/bios/apm.c @@ -906,6 +906,24 @@ apm_record_event(struct apm_softc *sc, u_int event_type) return (sc->sc_flags & SCFLAG_OCTL) ? 0 : 1; /* user may handle */ } +/* Power profile */ +static void +apm_power_profile(struct apm_softc *sc) +{ + int state; + struct apm_info info; + static int apm_acline = 0; + + if (apm_get_info(&info)) + return; + + if (apm_acline != info.ai_acline) { + apm_acline = info.ai_acline; + state = apm_acline ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY; + power_profile_set_state(state); + } +} + /* Process APM event */ static void apm_processevent(void) @@ -975,6 +993,7 @@ apm_processevent(void) break; OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME); apm_record_event(sc, apm_event); @@ -982,6 +1001,7 @@ apm_processevent(void) break; OPMEV_DEBUGMESSAGE(PMEV_CAPABILITIESCHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; case PMEV_NOEVENT: break; diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index 156d2c0..6aa0967 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -48,6 +48,7 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/power.h> #include <machine/asmacros.h> #include <machine/clock.h> @@ -1135,9 +1136,40 @@ static u_int crusoe_longrun; static u_int crusoe_frequency; static u_int crusoe_voltage; static u_int crusoe_percentage; +static u_int crusoe_performance_longrun = LONGRUN_MODE_PERFORMANCE; +static u_int crusoe_economy_longrun = LONGRUN_MODE_ECONOMY; static struct sysctl_ctx_list crusoe_sysctl_ctx; static struct sysctl_oid *crusoe_sysctl_tree; +static void +tmx86_longrun_power_profile(void *arg) +{ + int state; + u_int new; + + state = power_profile_get_state(); + if (state != POWER_PROFILE_PERFORMANCE && + state != POWER_PROFILE_ECONOMY) { + return; + } + + switch (state) { + case POWER_PROFILE_PERFORMANCE: + new =crusoe_performance_longrun; + break; + case POWER_PROFILE_ECONOMY: + new = crusoe_economy_longrun; + break; + default: + new = tmx86_get_longrun_mode(); + break; + } + + if (tmx86_get_longrun_mode() != new) { + tmx86_set_longrun_mode(new); + } +} + static int tmx86_longrun_sysctl(SYSCTL_HANDLER_ARGS) { @@ -1175,6 +1207,34 @@ tmx86_status_sysctl(SYSCTL_HANDLER_ARGS) return (error); } +static int +tmx86_longrun_profile_sysctl(SYSCTL_HANDLER_ARGS) +{ + u_int32_t *argp; + u_int32_t arg; + int error; + + argp = (u_int32_t *)oidp->oid_arg1; + arg = *argp; + error = sysctl_handle_int(oidp, &arg, 0, req); + + /* error or no new value */ + if ((error != 0) || (req->newptr == NULL)) + return (error); + + /* range check */ + if (arg >= LONGRUN_MODE_UNKNOWN) + return (EINVAL); + + /* set new value and possibly switch */ + *argp = arg; + + tmx86_longrun_power_profile(NULL); + + return (0); + +} + static void setup_tmx86_longrun(void) { @@ -1205,6 +1265,16 @@ setup_tmx86_longrun(void) OID_AUTO, "percentage", CTLTYPE_INT | CTLFLAG_RD, &crusoe_percentage, 0, tmx86_status_sysctl, "I", "Processing performance (%)"); + SYSCTL_ADD_PROC(&crusoe_sysctl_ctx, SYSCTL_CHILDREN(crusoe_sysctl_tree), + OID_AUTO, "performance_longrun", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_RW, + &crusoe_performance_longrun, 0, tmx86_longrun_profile_sysctl, "I", ""); + SYSCTL_ADD_PROC(&crusoe_sysctl_ctx, SYSCTL_CHILDREN(crusoe_sysctl_tree), + OID_AUTO, "economy_longrun", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_RW, + &crusoe_economy_longrun, 0, tmx86_longrun_profile_sysctl, "I", ""); + + /* register performance profile change handler */ + EVENTHANDLER_REGISTER(power_profile_change, tmx86_longrun_power_profile, NULL, 0); + } static void diff --git a/sys/kern/subr_power.c b/sys/kern/subr_power.c index d73958c..7c96c9e 100644 --- a/sys/kern/subr_power.c +++ b/sys/kern/subr_power.c @@ -28,6 +28,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/proc.h> #include <sys/power.h> @@ -74,3 +75,33 @@ power_pm_suspend(int state) power_pm_fn(POWER_CMD_SUSPEND, power_pm_arg, state); } +/* + * Power profile. + */ + +static int power_profile_state = POWER_PROFILE_PERFORMANCE; + +int +power_profile_get_state(void) +{ + return (power_profile_state); +} + +void +power_profile_set_state(int state) +{ + int changed; + + if (state != power_profile_state) { + power_profile_state = state; + changed = 1; + printf("system power profile changed to '%s'\n", + (state == POWER_PROFILE_PERFORMANCE) ? "performance" : "economy"); + } else { + changed = 0; + } + + if (changed) + EVENTHANDLER_INVOKE(power_profile_change); +} + diff --git a/sys/modules/acpi/Makefile b/sys/modules/acpi/Makefile index 42a39df..e6f5c90 100644 --- a/sys/modules/acpi/Makefile +++ b/sys/modules/acpi/Makefile @@ -28,7 +28,7 @@ SRCS+= utglobal.c utinit.c utmath.c utmisc.c utobject.c utxface.c # OSD layer SRCS+= acpi.c acpi_acad.c acpi_battery.c acpi_button.c acpi_cmbat.c acpi_cpu.c -SRCS+= acpi_ec.c acpi_lid.c acpi_pcib.c acpi_powerprofile.c +SRCS+= acpi_ec.c acpi_lid.c acpi_pcib.c SRCS+= acpi_powerres.c acpi_resource.c acpi_thermal.c acpi_timer.c SRCS+= acpica_support.c SRCS+= OsdDebug.c diff --git a/sys/sys/power.h b/sys/sys/power.h index a94ed06..b870924 100644 --- a/sys/sys/power.h +++ b/sys/sys/power.h @@ -29,6 +29,8 @@ #ifndef _SYS_POWER_H_ #define _SYS_POWER_H_ +#include <sys/eventhandler.h> + /* Power management system type */ #define POWER_PM_TYPE_APM 0x00 #define POWER_PM_TYPE_ACPI 0x01 @@ -47,5 +49,17 @@ extern int power_pm_register(u_int, power_pm_fn_t, void *); extern u_int power_pm_get_type(void); extern void power_pm_suspend(int); +/* + * System power API. + */ +#define POWER_PROFILE_PERFORMANCE 0 +#define POWER_PROFILE_ECONOMY 1 + +extern int power_profile_get_state(void); +extern void power_profile_set_state(int); + +typedef void (*power_profile_change_hook)(void *); +EVENTHANDLER_DECLARE(power_profile_change, power_profile_change_hook); + #endif /* !_SYS_POWER_H_ */ |