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
This commit is contained in:
parent
2d0639e55d
commit
899ccf541a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91640
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))) {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user