Style and whitespace changes. Also, make the ivar functions non-inline
since inlining failed due to the size of BUS_*
This commit is contained in:
parent
772a9659d9
commit
be2b179704
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
/*
|
||||
@ -50,9 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
* _PSS and _PPC.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_PROCESSOR
|
||||
ACPI_MODULE_NAME("PROCESSOR")
|
||||
|
||||
@ -64,15 +61,16 @@ struct acpi_cpu_softc {
|
||||
|
||||
/* CPU throttling control register */
|
||||
struct resource *cpu_p_blk;
|
||||
#define CPU_GET_P_CNT(sc) (bus_space_read_4(rman_get_bustag((sc)->cpu_p_blk), \
|
||||
rman_get_bushandle((sc)->cpu_p_blk), \
|
||||
0))
|
||||
#define CPU_SET_P_CNT(sc, val) (bus_space_write_4(rman_get_bustag((sc)->cpu_p_blk), \
|
||||
rman_get_bushandle((sc)->cpu_p_blk), \
|
||||
0, (val)))
|
||||
#define CPU_P_CNT_THT_EN (1<<4)
|
||||
#define CPU_P_CNT_THT_EN (1<<4)
|
||||
};
|
||||
|
||||
#define CPU_GET_P_CNT(sc) \
|
||||
(bus_space_read_4(rman_get_bustag((sc)->cpu_p_blk), \
|
||||
rman_get_bushandle((sc)->cpu_p_blk), 0))
|
||||
#define CPU_SET_P_CNT(sc, val) \
|
||||
(bus_space_write_4(rman_get_bustag((sc)->cpu_p_blk), \
|
||||
rman_get_bushandle((sc)->cpu_p_blk), 0, (val)))
|
||||
|
||||
/*
|
||||
* Speeds are stored in counts, from 1 - CPU_MAX_SPEED, and
|
||||
* reported to the user in tenths of a percent.
|
||||
@ -83,7 +81,8 @@ static u_int32_t cpu_duty_width;
|
||||
#define CPU_SPEED_PERCENT(x) ((1000 * (x)) / CPU_MAX_SPEED)
|
||||
#define CPU_SPEED_PRINTABLE(x) (CPU_SPEED_PERCENT(x) / 10),(CPU_SPEED_PERCENT(x) % 10)
|
||||
|
||||
static u_int32_t cpu_smi_cmd; /* should be a generic way to do this */
|
||||
/* XXX Should be a generic way to do this */
|
||||
static u_int32_t cpu_smi_cmd;
|
||||
static u_int8_t cpu_pstate_cnt;
|
||||
|
||||
static u_int32_t cpu_current_state;
|
||||
@ -124,12 +123,13 @@ DRIVER_MODULE(acpi_cpu, acpi, acpi_cpu_driver, acpi_cpu_devclass, 0, 0);
|
||||
static int
|
||||
acpi_cpu_probe(device_t dev)
|
||||
{
|
||||
if (!acpi_disabled("cpu") &&
|
||||
(acpi_get_type(dev) == ACPI_TYPE_PROCESSOR)) {
|
||||
device_set_desc(dev, "CPU"); /* XXX get more verbose description? */
|
||||
return(0);
|
||||
if (!acpi_disabled("cpu") && acpi_get_type(dev) == ACPI_TYPE_PROCESSOR) {
|
||||
/* XXX get more verbose description? */
|
||||
device_set_desc(dev, "CPU");
|
||||
return (0);
|
||||
}
|
||||
return(ENXIO);
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -153,71 +153,79 @@ acpi_cpu_attach(device_t dev)
|
||||
sc->cpu_dev = dev;
|
||||
sc->cpu_handle = acpi_get_handle(dev);
|
||||
|
||||
/*
|
||||
* Get global parameters from the FADT.
|
||||
*/
|
||||
/* Get global parameters from the FADT. */
|
||||
if (device_get_unit(sc->cpu_dev) == 0) {
|
||||
cpu_duty_offset = AcpiGbl_FADT->DutyOffset;
|
||||
cpu_duty_width = AcpiGbl_FADT->DutyWidth;
|
||||
cpu_smi_cmd = AcpiGbl_FADT->SmiCmd;
|
||||
cpu_pstate_cnt = AcpiGbl_FADT->PstateCnt;
|
||||
|
||||
/* validate the offset/width */
|
||||
/* Validate the offset/width */
|
||||
if (cpu_duty_width > 0) {
|
||||
duty_end = cpu_duty_offset + cpu_duty_width - 1;
|
||||
/* check that it fits */
|
||||
if (duty_end > 31) {
|
||||
printf("acpi_cpu: CLK_VAL field overflows P_CNT register\n");
|
||||
cpu_duty_width = 0;
|
||||
}
|
||||
/* check for overlap with the THT_EN bit */
|
||||
if ((cpu_duty_offset <= 4) && (duty_end >= 4)) {
|
||||
printf("acpi_cpu: CLK_VAL field overlaps THT_EN bit\n");
|
||||
cpu_duty_width = 0;
|
||||
}
|
||||
duty_end = cpu_duty_offset + cpu_duty_width - 1;
|
||||
|
||||
/* Check that it fits */
|
||||
if (duty_end > 31) {
|
||||
printf("acpi_cpu: CLK_VAL field overflows P_CNT register\n");
|
||||
cpu_duty_width = 0;
|
||||
}
|
||||
|
||||
/* Check for overlap with the THT_EN bit */
|
||||
if (cpu_duty_offset <= 4 && duty_end >= 4) {
|
||||
printf("acpi_cpu: CLK_VAL field overlaps THT_EN bit\n");
|
||||
cpu_duty_width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the throttling process once the probe phase completes, if we think that
|
||||
* it's going to be useful. If the duty width value is zero, there are no significant
|
||||
* bits in the register and thus no throttled states.
|
||||
* Start the throttling process once the probe phase completes, if we
|
||||
* think that it's going to be useful. If the duty width value is
|
||||
* zero, there are no significant bits in the register and thus no
|
||||
* throttled states.
|
||||
*/
|
||||
if (cpu_duty_width > 0) {
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cpu_init_throttling, NULL);
|
||||
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cpu_init_throttling,
|
||||
NULL);
|
||||
acpi_sc = acpi_device_get_parent_softc(dev);
|
||||
sysctl_ctx_init(&acpi_cpu_sysctl_ctx);
|
||||
acpi_cpu_sysctl_tree = SYSCTL_ADD_NODE(&acpi_cpu_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
|
||||
OID_AUTO, "cpu", CTLFLAG_RD, 0, "");
|
||||
SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
|
||||
OID_AUTO, "cpu", CTLFLAG_RD, 0, "");
|
||||
|
||||
SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "max_speed", CTLFLAG_RD,
|
||||
&cpu_max_state, 0, "maximum CPU speed");
|
||||
SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "current_speed", CTLFLAG_RD,
|
||||
&cpu_current_state, 0, "current CPU speed");
|
||||
SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "performance_speed", CTLTYPE_INT | CTLFLAG_RW,
|
||||
&cpu_performance_state, 0, acpi_cpu_speed_sysctl, "I", "");
|
||||
SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "economy_speed", CTLTYPE_INT | CTLFLAG_RW,
|
||||
&cpu_economy_state, 0, acpi_cpu_speed_sysctl, "I", "");
|
||||
SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "performance_speed",
|
||||
CTLTYPE_INT | CTLFLAG_RW, &cpu_performance_state,
|
||||
0, acpi_cpu_speed_sysctl, "I", "");
|
||||
SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
|
||||
OID_AUTO, "economy_speed",
|
||||
CTLTYPE_INT | CTLFLAG_RW, &cpu_economy_state,
|
||||
0, acpi_cpu_speed_sysctl, "I", "");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the processor object.
|
||||
*/
|
||||
/* Get the processor object. */
|
||||
buf.Pointer = &processor;
|
||||
buf.Length = sizeof(processor);
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf))) {
|
||||
device_printf(sc->cpu_dev, "couldn't get Processor object - %s\n", AcpiFormatException(status));
|
||||
return_VALUE(ENXIO);
|
||||
status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
device_printf(sc->cpu_dev, "couldn't get Processor object - %s\n",
|
||||
AcpiFormatException(status));
|
||||
return_VALUE (ENXIO);
|
||||
}
|
||||
if (processor.Type != ACPI_TYPE_PROCESSOR) {
|
||||
device_printf(sc->cpu_dev, "Processor object has bad type %d\n", processor.Type);
|
||||
return_VALUE(ENXIO);
|
||||
device_printf(sc->cpu_dev, "Processor object has bad type %d\n",
|
||||
processor.Type);
|
||||
return_VALUE (ENXIO);
|
||||
}
|
||||
sc->cpu_id = processor.Processor.ProcId;
|
||||
|
||||
@ -236,18 +244,21 @@ acpi_cpu_attach(device_t dev)
|
||||
p_blk_length = processor.Processor.PblkLength;
|
||||
|
||||
/* allocate bus space if possible */
|
||||
if ((p_blk > 0) && (p_blk_length == 6)) {
|
||||
if (p_blk > 0 && p_blk_length == 6) {
|
||||
rid = 0;
|
||||
bus_set_resource(sc->cpu_dev, SYS_RES_IOPORT, rid, p_blk, p_blk_length);
|
||||
sc->cpu_p_blk = bus_alloc_resource(sc->cpu_dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
bus_set_resource(sc->cpu_dev, SYS_RES_IOPORT, rid, p_blk,
|
||||
p_blk_length);
|
||||
sc->cpu_p_blk = bus_alloc_resource(sc->cpu_dev, SYS_RES_IOPORT,
|
||||
&rid, 0, ~0, 1, RF_ACTIVE);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_IO, "acpi_cpu%d: throttling with P_BLK at 0x%x/%d%s\n",
|
||||
device_get_unit(sc->cpu_dev), p_blk, p_blk_length,
|
||||
sc->cpu_p_blk ? "" : " (shadowed)"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_IO, "acpi_cpu%d: throttling with P_BLK "
|
||||
"at 0x%x/%d%s\n", device_get_unit(sc->cpu_dev),
|
||||
p_blk, p_blk_length,
|
||||
sc->cpu_p_blk ? "" : " (shadowed)"));
|
||||
}
|
||||
}
|
||||
return_VALUE(0);
|
||||
|
||||
return_VALUE (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -264,36 +275,42 @@ acpi_cpu_init_throttling(void *arg)
|
||||
|
||||
ACPI_LOCK;
|
||||
|
||||
/* get set of CPU devices */
|
||||
/* Get set of CPU devices */
|
||||
devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices);
|
||||
|
||||
/* initialise throttling states */
|
||||
/* Initialise throttling states */
|
||||
cpu_max_state = CPU_MAX_SPEED;
|
||||
cpu_performance_state = cpu_max_state;
|
||||
cpu_economy_state = cpu_performance_state / 2;
|
||||
if (cpu_economy_state == 0) /* 0 is 'reserved' */
|
||||
|
||||
/* 0 is 'reserved' */
|
||||
if (cpu_economy_state == 0)
|
||||
cpu_economy_state++;
|
||||
if (TUNABLE_INT_FETCH("hw.acpi.cpu.performance_speed",
|
||||
&cpu_temp_speed) && cpu_temp_speed > 0 &&
|
||||
cpu_temp_speed <= cpu_max_state)
|
||||
if (TUNABLE_INT_FETCH("hw.acpi.cpu.performance_speed", &cpu_temp_speed) &&
|
||||
cpu_temp_speed > 0 && cpu_temp_speed <= cpu_max_state) {
|
||||
|
||||
cpu_performance_state = cpu_temp_speed;
|
||||
if (TUNABLE_INT_FETCH("hw.acpi.cpu.economy_speed",
|
||||
&cpu_temp_speed) && cpu_temp_speed > 0 &&
|
||||
cpu_temp_speed <= cpu_max_state)
|
||||
cpu_economy_state = cpu_temp_speed;
|
||||
|
||||
/* register performance profile change handler */
|
||||
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) {
|
||||
/* XXX should be a generic interface for this */
|
||||
AcpiOsWritePort(cpu_smi_cmd, cpu_pstate_cnt, 8);
|
||||
}
|
||||
if (TUNABLE_INT_FETCH("hw.acpi.cpu.economy_speed", &cpu_temp_speed) &&
|
||||
cpu_temp_speed > 0 && cpu_temp_speed <= cpu_max_state) {
|
||||
|
||||
cpu_economy_state = cpu_temp_speed;
|
||||
}
|
||||
|
||||
/* Register performance profile change handler */
|
||||
EVENTHANDLER_REGISTER(power_profile_change, acpi_cpu_power_profile, NULL,
|
||||
0);
|
||||
|
||||
/*
|
||||
* If ACPI 2.0+, signal platform that we are taking over throttling
|
||||
* XXX should be a generic interface for this
|
||||
*/
|
||||
if (cpu_pstate_cnt != 0)
|
||||
AcpiOsWritePort(cpu_smi_cmd, cpu_pstate_cnt, 8);
|
||||
|
||||
ACPI_UNLOCK;
|
||||
|
||||
/* set initial speed */
|
||||
/* Set initial speed */
|
||||
acpi_cpu_power_profile(NULL);
|
||||
|
||||
printf("acpi_cpu: throttling enabled, %d steps (100%% to %d.%d%%), "
|
||||
@ -315,32 +332,31 @@ acpi_cpu_set_speed(u_int32_t speed)
|
||||
|
||||
ACPI_ASSERTLOCK;
|
||||
|
||||
/* iterate over processors */
|
||||
/* Iterate over processors */
|
||||
for (i = 0; i < cpu_ndevices; i++) {
|
||||
sc = device_get_softc(cpu_devices[i]);
|
||||
if (sc->cpu_p_blk == NULL)
|
||||
continue;
|
||||
|
||||
/* get the current P_CNT value and disable throttling */
|
||||
/* Get the current P_CNT value and disable throttling */
|
||||
p_cnt = CPU_GET_P_CNT(sc);
|
||||
p_cnt &= ~CPU_P_CNT_THT_EN;
|
||||
CPU_SET_P_CNT(sc, p_cnt);
|
||||
|
||||
/* if we're at maximum speed, that's all */
|
||||
/* If we're at maximum speed, that's all */
|
||||
if (speed < CPU_MAX_SPEED) {
|
||||
|
||||
/* mask the old CLK_VAL off and or-in the new value */
|
||||
/* Mask the old CLK_VAL off and or-in the new value */
|
||||
clk_val = CPU_MAX_SPEED << cpu_duty_offset;
|
||||
p_cnt &= ~clk_val;
|
||||
p_cnt |= (speed << cpu_duty_offset);
|
||||
|
||||
/* write the new P_CNT value and then enable throttling */
|
||||
/* Write the new P_CNT value and then enable throttling */
|
||||
CPU_SET_P_CNT(sc, p_cnt);
|
||||
p_cnt |= CPU_P_CNT_THT_EN;
|
||||
CPU_SET_P_CNT(sc, p_cnt);
|
||||
}
|
||||
ACPI_VPRINT(sc->cpu_dev, acpi_device_get_parent_softc(sc->cpu_dev),
|
||||
"set speed to %d.%d%%\n", CPU_SPEED_PRINTABLE(speed));
|
||||
"set speed to %d.%d%%\n", CPU_SPEED_PRINTABLE(speed));
|
||||
}
|
||||
cpu_current_state = speed;
|
||||
}
|
||||
@ -358,10 +374,8 @@ acpi_cpu_power_profile(void *arg)
|
||||
ACPI_LOCK_DECL;
|
||||
|
||||
state = power_profile_get_state();
|
||||
if (state != POWER_PROFILE_PERFORMANCE &&
|
||||
state != POWER_PROFILE_ECONOMY) {
|
||||
if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY)
|
||||
return;
|
||||
}
|
||||
|
||||
ACPI_LOCK;
|
||||
|
||||
@ -400,17 +414,15 @@ acpi_cpu_speed_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
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 < 1) || (arg > cpu_max_state))
|
||||
return(EINVAL);
|
||||
/* Error or no new value */
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
if (arg < 1 || arg > cpu_max_state)
|
||||
return (EINVAL);
|
||||
|
||||
/* set new value and possibly switch */
|
||||
/* Set new value and possibly switch */
|
||||
*argp = arg;
|
||||
acpi_cpu_power_profile(NULL);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
@ -37,12 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_BUTTON
|
||||
ACPI_MODULE_NAME("LID")
|
||||
|
||||
@ -81,13 +78,13 @@ DRIVER_MODULE(acpi_lid, acpi, acpi_lid_driver, acpi_lid_devclass, 0, 0);
|
||||
static int
|
||||
acpi_lid_probe(device_t dev)
|
||||
{
|
||||
if ((acpi_get_type(dev) == ACPI_TYPE_DEVICE) &&
|
||||
!acpi_disabled("lid") &&
|
||||
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("lid") &&
|
||||
acpi_MatchHid(dev, "PNP0C0D")) {
|
||||
|
||||
device_set_desc(dev, "Control Method Lid Switch");
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
return(ENXIO);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -101,12 +98,12 @@ acpi_lid_attach(device_t dev)
|
||||
sc->lid_dev = dev;
|
||||
sc->lid_handle = acpi_get_handle(dev);
|
||||
|
||||
/*
|
||||
* Install notification handler
|
||||
*/
|
||||
AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY, acpi_lid_notify_handler, sc);
|
||||
/* Install notification handler */
|
||||
AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_lid_notify_handler, sc);
|
||||
acpi_device_enable_wake_capability(sc->lid_handle, 1);
|
||||
return_VALUE(0);
|
||||
|
||||
return_VALUE (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -130,6 +127,7 @@ acpi_lid_notify_status_changed(void *arg)
|
||||
{
|
||||
struct acpi_lid_softc *sc;
|
||||
struct acpi_softc *acpi_sc;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
@ -140,22 +138,21 @@ acpi_lid_notify_status_changed(void *arg)
|
||||
* Zero: The lid is closed
|
||||
* Non-zero: The lid is open
|
||||
*/
|
||||
if (ACPI_FAILURE(acpi_EvaluateInteger(sc->lid_handle, "_LID", &sc->lid_status)))
|
||||
status = acpi_EvaluateInteger(sc->lid_handle, "_LID", &sc->lid_status);
|
||||
if (ACPI_FAILURE(status))
|
||||
return_VOID;
|
||||
|
||||
acpi_sc = acpi_device_get_parent_softc(sc->lid_dev);
|
||||
if (acpi_sc == NULL) {
|
||||
if (acpi_sc == NULL)
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
ACPI_VPRINT(sc->lid_dev, acpi_sc,
|
||||
"Lid %s\n", sc->lid_status ? "opened" : "closed");
|
||||
ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n",
|
||||
sc->lid_status ? "opened" : "closed");
|
||||
|
||||
if (sc->lid_status == 0) {
|
||||
if (sc->lid_status == 0)
|
||||
EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
|
||||
} else {
|
||||
else
|
||||
EVENTHANDLER_INVOKE(acpi_wakeup_event, acpi_sc->acpi_lid_switch_sx);
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
@ -172,11 +169,13 @@ acpi_lid_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
|
||||
switch (notify) {
|
||||
case ACPI_NOTIFY_STATUS_CHANGED:
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_lid_notify_status_changed, sc);
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_LO,
|
||||
acpi_lid_notify_status_changed, sc);
|
||||
break;
|
||||
default:
|
||||
break; /* unknown notification value */
|
||||
break;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
|
@ -27,27 +27,14 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_acpi.h" /* XXX trim includes */
|
||||
#include "opt_acpi.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ctype.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
#include <dev/acpica/acpiio.h>
|
||||
|
||||
/*
|
||||
* ACPI power resource management.
|
||||
@ -70,62 +57,58 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources");
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_POWER
|
||||
ACPI_MODULE_NAME("POWERRES")
|
||||
|
||||
/* return values from _STA on a power resource */
|
||||
/* Return values from _STA on a power resource */
|
||||
#define ACPI_PWR_OFF 0
|
||||
#define ACPI_PWR_ON 1
|
||||
|
||||
/*
|
||||
* A relationship between a power resource and a consumer.
|
||||
*/
|
||||
/* A relationship between a power resource and a consumer. */
|
||||
struct acpi_powerreference {
|
||||
struct acpi_powerconsumer *ar_consumer;
|
||||
struct acpi_powerresource *ar_resource;
|
||||
TAILQ_ENTRY(acpi_powerreference) ar_rlink; /* link on resource list */
|
||||
TAILQ_ENTRY(acpi_powerreference) ar_clink; /* link on consumer */
|
||||
struct acpi_powerconsumer *ar_consumer;
|
||||
struct acpi_powerresource *ar_resource;
|
||||
TAILQ_ENTRY(acpi_powerreference) ar_rlink; /* link on resource list */
|
||||
TAILQ_ENTRY(acpi_powerreference) ar_clink; /* link on consumer */
|
||||
};
|
||||
|
||||
/*
|
||||
* A power-managed device.
|
||||
*/
|
||||
/* A power-managed device. */
|
||||
struct acpi_powerconsumer {
|
||||
ACPI_HANDLE ac_consumer; /* device which is powered */
|
||||
int ac_state;
|
||||
TAILQ_ENTRY(acpi_powerconsumer) ac_link;
|
||||
TAILQ_HEAD(,acpi_powerreference) ac_references;
|
||||
/* Device which is powered */
|
||||
ACPI_HANDLE ac_consumer;
|
||||
int ac_state;
|
||||
TAILQ_ENTRY(acpi_powerconsumer) ac_link;
|
||||
TAILQ_HEAD(,acpi_powerreference) ac_references;
|
||||
};
|
||||
|
||||
/*
|
||||
* A power resource.
|
||||
*/
|
||||
/* A power resource. */
|
||||
struct acpi_powerresource {
|
||||
TAILQ_ENTRY(acpi_powerresource) ap_link;
|
||||
TAILQ_HEAD(,acpi_powerreference) ap_references;
|
||||
ACPI_HANDLE ap_resource; /* the resource's handle */
|
||||
ACPI_INTEGER ap_systemlevel;
|
||||
ACPI_INTEGER ap_order;
|
||||
TAILQ_ENTRY(acpi_powerresource) ap_link;
|
||||
TAILQ_HEAD(,acpi_powerreference) ap_references;
|
||||
ACPI_HANDLE ap_resource;
|
||||
ACPI_INTEGER ap_systemlevel;
|
||||
ACPI_INTEGER ap_order;
|
||||
};
|
||||
|
||||
static TAILQ_HEAD(acpi_powerresource_list, acpi_powerresource) acpi_powerresources;
|
||||
static TAILQ_HEAD(acpi_powerconsumer_list, acpi_powerconsumer) acpi_powerconsumers;
|
||||
static TAILQ_HEAD(acpi_powerresource_list, acpi_powerresource)
|
||||
acpi_powerresources;
|
||||
static TAILQ_HEAD(acpi_powerconsumer_list, acpi_powerconsumer)
|
||||
acpi_powerconsumers;
|
||||
|
||||
static ACPI_STATUS acpi_pwr_register_consumer(ACPI_HANDLE consumer);
|
||||
static ACPI_STATUS acpi_pwr_deregister_consumer(ACPI_HANDLE consumer);
|
||||
static ACPI_STATUS acpi_pwr_register_resource(ACPI_HANDLE res);
|
||||
static ACPI_STATUS acpi_pwr_deregister_resource(ACPI_HANDLE res);
|
||||
static void acpi_pwr_reference_resource(ACPI_OBJECT *obj, void *arg);
|
||||
static ACPI_STATUS acpi_pwr_switch_power(void);
|
||||
static struct acpi_powerresource *acpi_pwr_find_resource(ACPI_HANDLE res);
|
||||
static struct acpi_powerconsumer *acpi_pwr_find_consumer(ACPI_HANDLE consumer);
|
||||
static ACPI_STATUS acpi_pwr_register_consumer(ACPI_HANDLE consumer);
|
||||
static ACPI_STATUS acpi_pwr_deregister_consumer(ACPI_HANDLE consumer);
|
||||
static ACPI_STATUS acpi_pwr_register_resource(ACPI_HANDLE res);
|
||||
static ACPI_STATUS acpi_pwr_deregister_resource(ACPI_HANDLE res);
|
||||
static void acpi_pwr_reference_resource(ACPI_OBJECT *obj,
|
||||
void *arg);
|
||||
static ACPI_STATUS acpi_pwr_switch_power(void);
|
||||
static struct acpi_powerresource
|
||||
*acpi_pwr_find_resource(ACPI_HANDLE res);
|
||||
static struct acpi_powerconsumer
|
||||
*acpi_pwr_find_consumer(ACPI_HANDLE consumer);
|
||||
|
||||
/*
|
||||
* Initialise our lists.
|
||||
*/
|
||||
/* Initialise our lists. */
|
||||
static void
|
||||
acpi_pwr_init(void *junk)
|
||||
{
|
||||
@ -152,11 +135,11 @@ acpi_pwr_register_resource(ACPI_HANDLE res)
|
||||
rp = NULL;
|
||||
buf.Pointer = NULL;
|
||||
|
||||
/* look to see if we know about this resource */
|
||||
/* Look to see if we know about this resource */
|
||||
if (acpi_pwr_find_resource(res) != NULL)
|
||||
return_ACPI_STATUS(AE_OK); /* already know about it */
|
||||
return_ACPI_STATUS (AE_OK); /* already know about it */
|
||||
|
||||
/* allocate a new resource */
|
||||
/* Allocate a new resource */
|
||||
if ((rp = malloc(sizeof(*rp), M_ACPIPWR, M_NOWAIT | M_ZERO)) == NULL) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto out;
|
||||
@ -164,7 +147,7 @@ acpi_pwr_register_resource(ACPI_HANDLE res)
|
||||
TAILQ_INIT(&rp->ap_references);
|
||||
rp->ap_resource = res;
|
||||
|
||||
/* get the Power Resource object */
|
||||
/* Get the Power Resource object */
|
||||
buf.Length = ACPI_ALLOCATE_BUFFER;
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(res, NULL, NULL, &buf))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "no power resource object\n"));
|
||||
@ -172,35 +155,40 @@ acpi_pwr_register_resource(ACPI_HANDLE res)
|
||||
}
|
||||
obj = buf.Pointer;
|
||||
if (obj->Type != ACPI_TYPE_POWER) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "questionable power resource object %s\n", acpi_name(res)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"questionable power resource object %s\n",
|
||||
acpi_name(res)));
|
||||
status = AE_TYPE;
|
||||
goto out;
|
||||
}
|
||||
rp->ap_systemlevel = obj->PowerResource.SystemLevel;
|
||||
rp->ap_order = obj->PowerResource.ResourceOrder;
|
||||
|
||||
/* sort the resource into the list */
|
||||
/* Sort the resource into the list */
|
||||
status = AE_OK;
|
||||
srp = TAILQ_FIRST(&acpi_powerresources);
|
||||
if ((srp == NULL) || (rp->ap_order < srp->ap_order)) {
|
||||
if (srp == NULL || rp->ap_order < srp->ap_order) {
|
||||
TAILQ_INSERT_HEAD(&acpi_powerresources, rp, ap_link);
|
||||
goto done;
|
||||
}
|
||||
TAILQ_FOREACH(srp, &acpi_powerresources, ap_link)
|
||||
TAILQ_FOREACH(srp, &acpi_powerresources, ap_link) {
|
||||
if (rp->ap_order < srp->ap_order) {
|
||||
TAILQ_INSERT_BEFORE(srp, rp, ap_link);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&acpi_powerresources, rp, ap_link);
|
||||
|
||||
done:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "registered power resource %s\n", acpi_name(res)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"registered power resource %s\n", acpi_name(res)));
|
||||
|
||||
out:
|
||||
if (buf.Pointer != NULL)
|
||||
AcpiOsFree(buf.Pointer);
|
||||
if (ACPI_FAILURE(status) && (rp != NULL))
|
||||
if (ACPI_FAILURE(status) && rp != NULL)
|
||||
free(rp, M_ACPIPWR);
|
||||
return_ACPI_STATUS(status);
|
||||
return_ACPI_STATUS (status);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -215,21 +203,22 @@ acpi_pwr_deregister_resource(ACPI_HANDLE res)
|
||||
|
||||
rp = NULL;
|
||||
|
||||
/* find the resource */
|
||||
/* Find the resource */
|
||||
if ((rp = acpi_pwr_find_resource(res)) == NULL)
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
|
||||
/* check that there are no consumers referencing this resource */
|
||||
/* Check that there are no consumers referencing this resource */
|
||||
if (TAILQ_FIRST(&rp->ap_references) != NULL)
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
|
||||
/* pull it off the list and free it */
|
||||
/* Pull it off the list and free it */
|
||||
TAILQ_REMOVE(&acpi_powerresources, rp, ap_link);
|
||||
free(rp, M_ACPIPWR);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power resource %s\n", acpi_name(res)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power resource %s\n",
|
||||
acpi_name(res)));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -244,22 +233,24 @@ acpi_pwr_register_consumer(ACPI_HANDLE consumer)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
/* check to see whether we know about this consumer already */
|
||||
/* Check to see whether we know about this consumer already */
|
||||
if ((pc = acpi_pwr_find_consumer(consumer)) != NULL)
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
|
||||
/* allocate a new power consumer */
|
||||
/* Allocate a new power consumer */
|
||||
if ((pc = malloc(sizeof(*pc), M_ACPIPWR, M_NOWAIT)) == NULL)
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
TAILQ_INSERT_HEAD(&acpi_powerconsumers, pc, ac_link);
|
||||
TAILQ_INIT(&pc->ac_references);
|
||||
pc->ac_consumer = consumer;
|
||||
|
||||
pc->ac_state = ACPI_STATE_UNKNOWN; /* XXX we should try to find its current state */
|
||||
/* XXX we should try to find its current state */
|
||||
pc->ac_state = ACPI_STATE_UNKNOWN;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "registered power consumer %s\n", acpi_name(consumer)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "registered power consumer %s\n",
|
||||
acpi_name(consumer)));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -275,20 +266,21 @@ acpi_pwr_deregister_consumer(ACPI_HANDLE consumer)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
/* find the consumer */
|
||||
/* Find the consumer */
|
||||
if ((pc = acpi_pwr_find_consumer(consumer)) == NULL)
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
|
||||
/* make sure the consumer's not referencing anything right now */
|
||||
/* Make sure the consumer's not referencing anything right now */
|
||||
if (TAILQ_FIRST(&pc->ac_references) != NULL)
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
|
||||
/* pull the consumer off the list and free it */
|
||||
/* Pull the consumer off the list and free it */
|
||||
TAILQ_REMOVE(&acpi_powerconsumers, pc, ac_link);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power consumer %s\n", acpi_name(consumer)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power consumer %s\n",
|
||||
acpi_name(consumer)));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -308,20 +300,20 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
/* find the consumer */
|
||||
/* Find the consumer */
|
||||
if ((pc = acpi_pwr_find_consumer(consumer)) == NULL) {
|
||||
if (ACPI_FAILURE(status = acpi_pwr_register_consumer(consumer)))
|
||||
return_ACPI_STATUS(status);
|
||||
return_ACPI_STATUS (status);
|
||||
if ((pc = acpi_pwr_find_consumer(consumer)) == NULL) {
|
||||
return_ACPI_STATUS(AE_ERROR); /* something very wrong */
|
||||
return_ACPI_STATUS (AE_ERROR); /* something very wrong */
|
||||
}
|
||||
}
|
||||
|
||||
/* check for valid transitions */
|
||||
if ((pc->ac_state == ACPI_STATE_D3) && (state != ACPI_STATE_D0))
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER); /* can only go to D0 from D3 */
|
||||
/* Check for valid transitions */
|
||||
if (pc->ac_state == ACPI_STATE_D3 && state != ACPI_STATE_D0)
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER); /* can only go to D0 from D3 */
|
||||
|
||||
/* find transition mechanism(s) */
|
||||
/* Find transition mechanism(s) */
|
||||
switch(state) {
|
||||
case ACPI_STATE_D0:
|
||||
method_name = "_PS0";
|
||||
@ -340,10 +332,10 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
reslist_name = "_PR3";
|
||||
break;
|
||||
default:
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
}
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "setup to switch %s D%d -> D%d\n",
|
||||
acpi_name(consumer), pc->ac_state, state));
|
||||
acpi_name(consumer), pc->ac_state, state));
|
||||
|
||||
/*
|
||||
* Verify that this state is supported, ie. one of method or
|
||||
@ -361,26 +353,25 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
method_handle = NULL;
|
||||
if (ACPI_FAILURE(AcpiGetHandle(consumer, reslist_name, &reslist_handle)))
|
||||
reslist_handle = NULL;
|
||||
if ((reslist_handle == NULL) && (method_handle == NULL)) {
|
||||
if (reslist_handle == NULL && method_handle == NULL) {
|
||||
if (state == ACPI_STATE_D0) {
|
||||
pc->ac_state = ACPI_STATE_D0;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
if (state != ACPI_STATE_D3) {
|
||||
if (state != ACPI_STATE_D3)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* turn off the resources listed in _PR0 to go to D3. */
|
||||
if (ACPI_FAILURE(AcpiGetHandle(consumer, "_PR0", &pr0_handle))) {
|
||||
/* Turn off the resources listed in _PR0 to go to D3. */
|
||||
if (ACPI_FAILURE(AcpiGetHandle(consumer, "_PR0", &pr0_handle)))
|
||||
goto bad;
|
||||
}
|
||||
reslist_buffer.Length = ACPI_ALLOCATE_BUFFER;
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(pr0_handle, NULL, NULL, &reslist_buffer))) {
|
||||
status = AcpiEvaluateObject(pr0_handle, NULL, NULL, &reslist_buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto bad;
|
||||
}
|
||||
reslist_object = (ACPI_OBJECT *)reslist_buffer.Pointer;
|
||||
if ((reslist_object->Type != ACPI_TYPE_PACKAGE) ||
|
||||
(reslist_object->Package.Count == 0)) {
|
||||
if (reslist_object->Type != ACPI_TYPE_PACKAGE ||
|
||||
reslist_object->Package.Count == 0) {
|
||||
|
||||
goto bad;
|
||||
}
|
||||
AcpiOsFree(reslist_buffer.Pointer);
|
||||
@ -393,27 +384,33 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
*/
|
||||
if (reslist_handle != NULL) {
|
||||
reslist_buffer.Length = ACPI_ALLOCATE_BUFFER;
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(reslist_handle, NULL, NULL, &reslist_buffer))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't evaluate resource list %s\n",
|
||||
acpi_name(reslist_handle)));
|
||||
status = AcpiEvaluateObject(reslist_handle, NULL, NULL,
|
||||
&reslist_buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"can't evaluate resource list %s\n",
|
||||
acpi_name(reslist_handle)));
|
||||
goto out;
|
||||
}
|
||||
reslist_object = (ACPI_OBJECT *)reslist_buffer.Pointer;
|
||||
if (reslist_object->Type != ACPI_TYPE_PACKAGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "resource list is not ACPI_TYPE_PACKAGE (%d)\n",
|
||||
reslist_object->Type));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"resource list is not ACPI_TYPE_PACKAGE (%d)\n",
|
||||
reslist_object->Type));
|
||||
status = AE_TYPE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we are ready to switch, so kill off any current power resource references.
|
||||
* Now we are ready to switch, so kill off any current power
|
||||
* resource references.
|
||||
*/
|
||||
res_changed = 0;
|
||||
while((pr = TAILQ_FIRST(&pc->ac_references)) != NULL) {
|
||||
res_changed = 1;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "removing reference to %s\n", acpi_name(pr->ar_resource->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "removing reference to %s\n",
|
||||
acpi_name(pr->ar_resource->ap_resource)));
|
||||
TAILQ_REMOVE(&pr->ar_resource->ap_references, pr, ar_rlink);
|
||||
TAILQ_REMOVE(&pc->ac_references, pr, ar_clink);
|
||||
free(pr, M_ACPIPWR);
|
||||
@ -427,7 +424,8 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
if (reslist_object != NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "referencing %d new resources\n",
|
||||
reslist_object->Package.Count));
|
||||
acpi_ForeachPackageObject(reslist_object, acpi_pwr_reference_resource, pc);
|
||||
acpi_ForeachPackageObject(reslist_object, acpi_pwr_reference_resource,
|
||||
pc);
|
||||
res_changed = 1;
|
||||
}
|
||||
|
||||
@ -436,36 +434,43 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
|
||||
* pass now.
|
||||
*/
|
||||
if (ACPI_FAILURE(status = acpi_pwr_switch_power())) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "failed to correctly switch resources to move %s to D%d\n",
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"failed to switch resources from %s to D%d\n",
|
||||
acpi_name(consumer), state));
|
||||
goto out; /* XXX is this appropriate? Should we return to previous state? */
|
||||
|
||||
/* XXX is this appropriate? Should we return to previous state? */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* invoke power state switch method (if present) */
|
||||
/* Invoke power state switch method (if present) */
|
||||
if (method_handle != NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "invoking state transition method %s\n",
|
||||
acpi_name(method_handle)));
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(method_handle, NULL, NULL, NULL))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"invoking state transition method %s\n",
|
||||
acpi_name(method_handle)));
|
||||
status = AcpiEvaluateObject(method_handle, NULL, NULL, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "failed to set state - %s\n",
|
||||
AcpiFormatException(status)));
|
||||
AcpiFormatException(status)));
|
||||
pc->ac_state = ACPI_STATE_UNKNOWN;
|
||||
goto out; /* XXX Should we return to previous state? */
|
||||
|
||||
/* XXX Should we return to previous state? */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* transition was successful */
|
||||
/* Transition was successful */
|
||||
pc->ac_state = state;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
|
||||
bad:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "attempt to set unsupported state D%d\n",
|
||||
state));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"attempt to set unsupported state D%d\n", state));
|
||||
status = AE_BAD_PARAMETER;
|
||||
|
||||
out:
|
||||
if (reslist_buffer.Pointer != NULL)
|
||||
AcpiOsFree(reslist_buffer.Pointer);
|
||||
return_ACPI_STATUS(status);
|
||||
return_ACPI_STATUS (status);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -487,44 +492,48 @@ acpi_pwr_reference_resource(ACPI_OBJECT *obj, void *arg)
|
||||
switch (obj->Type) {
|
||||
case ACPI_TYPE_ANY:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "building reference from %s to %s\n",
|
||||
acpi_name(pc->ac_consumer), acpi_name(obj->Reference.Handle)));
|
||||
|
||||
acpi_name(pc->ac_consumer),
|
||||
acpi_name(obj->Reference.Handle)));
|
||||
res = obj->Reference.Handle;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "building reference from %s to %s\n",
|
||||
acpi_name(pc->ac_consumer), obj->String.Pointer));
|
||||
|
||||
/* get the handle of the resource */
|
||||
if (ACPI_FAILURE(status = AcpiGetHandle(NULL, obj->String.Pointer, &res))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "couldn't find power resource %s\n",
|
||||
obj->String.Pointer));
|
||||
/* Get the handle of the resource */
|
||||
status = AcpiGetHandle(NULL, obj->String.Pointer, &res);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"couldn't find power resource %s\n",
|
||||
obj->String.Pointer));
|
||||
return_VOID;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "don't know how to create a power reference to object type %d\n",
|
||||
obj->Type));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"can't create a power reference for object type %d\n",
|
||||
obj->Type));
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/* create/look up the resource */
|
||||
/* Create/look up the resource */
|
||||
if (ACPI_FAILURE(status = acpi_pwr_register_resource(res))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "couldn't register power resource %s - %s\n",
|
||||
obj->String.Pointer, AcpiFormatException(status)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"couldn't register power resource %s - %s\n",
|
||||
obj->String.Pointer, AcpiFormatException(status)));
|
||||
return_VOID;
|
||||
}
|
||||
if ((rp = acpi_pwr_find_resource(res)) == NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "power resource list corrupted\n"));
|
||||
return_VOID;
|
||||
}
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "found power resource %s\n", acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "found power resource %s\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
|
||||
/* create a reference between the consumer and resource */
|
||||
/* Create a reference between the consumer and resource */
|
||||
if ((pr = malloc(sizeof(*pr), M_ACPIPWR, M_NOWAIT | M_ZERO)) == NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "couldn't allocate memory for a power consumer reference\n"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"allocation failed for a power consumer reference\n"));
|
||||
return_VOID;
|
||||
}
|
||||
pr->ar_consumer = pc;
|
||||
@ -556,16 +565,20 @@ acpi_pwr_switch_power(void)
|
||||
*/
|
||||
TAILQ_FOREACH(rp, &acpi_powerresources, ap_link) {
|
||||
if (TAILQ_FIRST(&rp->ap_references) == NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s has no references, not turning on\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"%s has no references, not turning on\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we could cache this if we trusted it not to change under us */
|
||||
if (ACPI_FAILURE(status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur))) {
|
||||
/* We could cache this if we trusted it not to change under us */
|
||||
status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get status of %s - %d\n",
|
||||
acpi_name(rp->ap_resource), status));
|
||||
continue; /* XXX is this correct? Always switch if in doubt? */
|
||||
|
||||
/* XXX is this correct? Always switch if in doubt? */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -574,32 +587,40 @@ acpi_pwr_switch_power(void)
|
||||
* help much.
|
||||
*/
|
||||
if (cur != ACPI_PWR_ON) {
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "failed to switch %s on - %s\n",
|
||||
acpi_name(rp->ap_resource), AcpiFormatException(status)));
|
||||
status = AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"failed to switch %s on - %s\n",
|
||||
acpi_name(rp->ap_resource),
|
||||
AcpiFormatException(status)));
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s on\n", acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s on\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
}
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s is already on\n", acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s is already on\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sweep the list backwards turning things off.
|
||||
*/
|
||||
TAILQ_FOREACH_REVERSE(rp, &acpi_powerresources, acpi_powerresource_list, ap_link) {
|
||||
/* Sweep the list backwards turning things off. */
|
||||
TAILQ_FOREACH_REVERSE(rp, &acpi_powerresources, acpi_powerresource_list,
|
||||
ap_link) {
|
||||
|
||||
if (TAILQ_FIRST(&rp->ap_references) != NULL) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s has references, not turning off\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"%s has references, not turning off\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we could cache this if we trusted it not to change under us */
|
||||
if (ACPI_FAILURE(status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur))) {
|
||||
/* We could cache this if we trusted it not to change under us */
|
||||
status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get status of %s - %d\n",
|
||||
acpi_name(rp->ap_resource), status));
|
||||
continue; /* XXX is this correct? Always switch if in doubt? */
|
||||
/* XXX is this correct? Always switch if in doubt? */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -608,17 +629,23 @@ acpi_pwr_switch_power(void)
|
||||
* help much.
|
||||
*/
|
||||
if (cur != ACPI_PWR_OFF) {
|
||||
if (ACPI_FAILURE(status = AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL))) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "failed to switch %s off - %s\n",
|
||||
acpi_name(rp->ap_resource), AcpiFormatException(status)));
|
||||
status = AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"failed to switch %s off - %s\n",
|
||||
acpi_name(rp->ap_resource),
|
||||
AcpiFormatException(status)));
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s off\n", acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s off\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
}
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s is already off\n", acpi_name(rp->ap_resource)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s is already off\n",
|
||||
acpi_name(rp->ap_resource)));
|
||||
}
|
||||
}
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -631,10 +658,12 @@ acpi_pwr_find_resource(ACPI_HANDLE res)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
TAILQ_FOREACH(rp, &acpi_powerresources, ap_link)
|
||||
TAILQ_FOREACH(rp, &acpi_powerresources, ap_link) {
|
||||
if (rp->ap_resource == res)
|
||||
break;
|
||||
return_PTR(rp);
|
||||
}
|
||||
|
||||
return_PTR (rp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -647,9 +676,10 @@ acpi_pwr_find_consumer(ACPI_HANDLE consumer)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
TAILQ_FOREACH(pc, &acpi_powerconsumers, ac_link)
|
||||
TAILQ_FOREACH(pc, &acpi_powerconsumers, ac_link) {
|
||||
if (pc->ac_consumer == consumer)
|
||||
break;
|
||||
return_PTR(pc);
|
||||
}
|
||||
}
|
||||
|
||||
return_PTR (pc);
|
||||
}
|
||||
|
@ -38,12 +38,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_BUS
|
||||
ACPI_MODULE_NAME("RESOURCE")
|
||||
|
||||
@ -58,7 +55,8 @@ ACPI_MODULE_NAME("RESOURCE")
|
||||
* code for _PRS someday.
|
||||
*/
|
||||
ACPI_STATUS
|
||||
acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resource_set *set)
|
||||
acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
|
||||
struct acpi_parse_resource_set *set)
|
||||
{
|
||||
ACPI_BUFFER buf;
|
||||
ACPI_RESOURCE *res;
|
||||
@ -78,85 +76,79 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
* the PCI interrupt link.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fetch the device's current resources.
|
||||
*/
|
||||
/* Fetch the device's current resources. */
|
||||
buf.Length = ACPI_ALLOCATE_BUFFER;
|
||||
if (ACPI_FAILURE((status = AcpiGetCurrentResources(handle, &buf)))) {
|
||||
if (status != AE_NOT_FOUND)
|
||||
printf("can't fetch resources for %s - %s\n",
|
||||
acpi_name(handle), AcpiFormatException(status));
|
||||
return_ACPI_STATUS(status);
|
||||
return_ACPI_STATUS (status);
|
||||
}
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s - got %ld bytes of resources\n",
|
||||
acpi_name(handle), (long)buf.Length));
|
||||
acpi_name(handle), (long)buf.Length));
|
||||
set->set_init(dev, &context);
|
||||
|
||||
/*
|
||||
* Iterate through the resources
|
||||
*/
|
||||
/* Iterate through the resources */
|
||||
curr = buf.Pointer;
|
||||
last = (char *)buf.Pointer + buf.Length;
|
||||
while (curr < last) {
|
||||
res = (ACPI_RESOURCE *)curr;
|
||||
curr += res->Length;
|
||||
|
||||
/*
|
||||
* Handle the individual resource types
|
||||
*/
|
||||
/* Handle the individual resource types */
|
||||
switch(res->Id) {
|
||||
case ACPI_RSTYPE_END_TAG:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n"));
|
||||
curr = last;
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_FIXED_IO:
|
||||
if (res->Data.FixedIo.RangeLength <= 0)
|
||||
break;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedIo 0x%x/%d\n",
|
||||
res->Data.FixedIo.BaseAddress,
|
||||
res->Data.FixedIo.RangeLength));
|
||||
res->Data.FixedIo.BaseAddress,
|
||||
res->Data.FixedIo.RangeLength));
|
||||
set->set_ioport(dev, context,
|
||||
res->Data.FixedIo.BaseAddress,
|
||||
res->Data.FixedIo.RangeLength);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_IO:
|
||||
if (res->Data.Io.RangeLength <= 0)
|
||||
break;
|
||||
if (res->Data.Io.MinBaseAddress == res->Data.Io.MaxBaseAddress) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x/%d\n",
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.RangeLength));
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.RangeLength));
|
||||
set->set_ioport(dev, context,
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.RangeLength);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x-0x%x/%d\n",
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.MaxBaseAddress,
|
||||
res->Data.Io.RangeLength));
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.MaxBaseAddress,
|
||||
res->Data.Io.RangeLength));
|
||||
set->set_iorange(dev, context,
|
||||
res->Data.Io.MinBaseAddress,
|
||||
res->Data.Io.MaxBaseAddress,
|
||||
res->Data.Io.RangeLength, res->Data.Io.Alignment);
|
||||
res->Data.Io.RangeLength,
|
||||
res->Data.Io.Alignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_FIXED_MEM32:
|
||||
if (res->Data.FixedMemory32.RangeLength <= 0)
|
||||
break;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedMemory32 0x%x/%d\n",
|
||||
res->Data.FixedMemory32.RangeBaseAddress,
|
||||
res->Data.FixedMemory32.RangeLength));
|
||||
set->set_memory(dev, context, res->Data.FixedMemory32.RangeBaseAddress,
|
||||
set->set_memory(dev, context,
|
||||
res->Data.FixedMemory32.RangeBaseAddress,
|
||||
res->Data.FixedMemory32.RangeLength);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_MEM32:
|
||||
if (res->Data.Memory32.RangeLength <= 0)
|
||||
break;
|
||||
if (res->Data.Memory32.MinBaseAddress == res->Data.Memory32.MaxBaseAddress) {
|
||||
if (res->Data.Memory32.MinBaseAddress ==
|
||||
res->Data.Memory32.MaxBaseAddress) {
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x/%d\n",
|
||||
res->Data.Memory32.MinBaseAddress,
|
||||
res->Data.Memory32.RangeLength));
|
||||
@ -165,9 +157,9 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
res->Data.Memory32.RangeLength);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x-0x%x/%d\n",
|
||||
res->Data.Memory32.MinBaseAddress,
|
||||
res->Data.Memory32.MaxBaseAddress,
|
||||
res->Data.Memory32.RangeLength));
|
||||
res->Data.Memory32.MinBaseAddress,
|
||||
res->Data.Memory32.MaxBaseAddress,
|
||||
res->Data.Memory32.RangeLength));
|
||||
set->set_memoryrange(dev, context,
|
||||
res->Data.Memory32.MinBaseAddress,
|
||||
res->Data.Memory32.MaxBaseAddress,
|
||||
@ -175,21 +167,22 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
res->Data.Memory32.Alignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_MEM24:
|
||||
if (res->Data.Memory24.RangeLength <= 0)
|
||||
break;
|
||||
if (res->Data.Memory24.MinBaseAddress == res->Data.Memory24.MaxBaseAddress) {
|
||||
if (res->Data.Memory24.MinBaseAddress ==
|
||||
res->Data.Memory24.MaxBaseAddress) {
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x/%d\n",
|
||||
res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.RangeLength));
|
||||
res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.RangeLength));
|
||||
set->set_memory(dev, context, res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.RangeLength);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x-0x%x/%d\n",
|
||||
res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.MaxBaseAddress,
|
||||
res->Data.Memory24.RangeLength));
|
||||
res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.MaxBaseAddress,
|
||||
res->Data.Memory24.RangeLength));
|
||||
set->set_memoryrange(dev, context,
|
||||
res->Data.Memory24.MinBaseAddress,
|
||||
res->Data.Memory24.MaxBaseAddress,
|
||||
@ -197,7 +190,6 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
res->Data.Memory24.Alignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_IRQ:
|
||||
/*
|
||||
* from 1.0b 6.4.2
|
||||
@ -207,78 +199,79 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
set->set_irq(dev, context, res->Data.Irq.Interrupts,
|
||||
res->Data.Irq.NumberOfInterrupts);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_DMA:
|
||||
/*
|
||||
* from 1.0b 6.4.3
|
||||
* "This structure is repeated for each separate dma channel
|
||||
* required"
|
||||
*/
|
||||
|
||||
set->set_drq(dev, context, res->Data.Dma.Channels,
|
||||
res->Data.Dma.NumberOfChannels);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_START_DPF:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "start dependant functions\n"));
|
||||
set->set_start_dependant(dev, context,
|
||||
res->Data.StartDpf.CompatibilityPriority);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_END_DPF:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "end dependant functions\n"));
|
||||
set->set_end_dependant(dev, context);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_ADDRESS32:
|
||||
if (res->Data.Address32.AddressLength <= 0)
|
||||
break;
|
||||
if (res->Data.Address32.ProducerConsumer != ACPI_CONSUMER) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "ignored Address32 %s producer\n",
|
||||
(res->Data.Address32.ResourceType == ACPI_IO_RANGE) ?
|
||||
"IO" : "Memory"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"ignored Address32 %s producer\n",
|
||||
res->Data.Address32.ResourceType == ACPI_IO_RANGE ?
|
||||
"IO" : "Memory"));
|
||||
break;
|
||||
}
|
||||
if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE &&
|
||||
res->Data.Address32.ResourceType != ACPI_IO_RANGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"ignored Address32 for non-memory, non-I/O\n"));
|
||||
"ignored Address32 for non-memory, non-I/O\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((res->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED) &&
|
||||
(res->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED)) {
|
||||
if (res->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED &&
|
||||
res->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
|
||||
|
||||
if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address32/Memory 0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address32/Memory 0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
set->set_memory(dev, context,
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address32/IO 0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address32/IO 0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
set->set_ioport(dev, context,
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.AddressLength);
|
||||
}
|
||||
} else {
|
||||
if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address32/Memory 0x%x-0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address32/Memory 0x%x-0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
set->set_memoryrange(dev, context,
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
res->Data.Address32.AddressLength,
|
||||
res->Data.Address32.Granularity);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address32/IO 0x%x-0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address32/IO 0x%x-0x%x/%d\n",
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
res->Data.Address32.AddressLength));
|
||||
set->set_iorange(dev, context,
|
||||
res->Data.Address32.MinAddressRange,
|
||||
res->Data.Address32.MaxAddressRange,
|
||||
@ -287,14 +280,14 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_ADDRESS16:
|
||||
if (res->Data.Address16.AddressLength <= 0)
|
||||
break;
|
||||
if (res->Data.Address16.ProducerConsumer != ACPI_CONSUMER) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "ignored Address16 %s producer\n",
|
||||
(res->Data.Address16.ResourceType == ACPI_IO_RANGE) ?
|
||||
"IO" : "Memory"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"ignored Address16 %s producer\n",
|
||||
res->Data.Address16.ResourceType == ACPI_IO_RANGE ?
|
||||
"IO" : "Memory"));
|
||||
break;
|
||||
}
|
||||
if (res->Data.Address16.ResourceType != ACPI_MEMORY_RANGE &&
|
||||
@ -304,39 +297,44 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
break;
|
||||
}
|
||||
|
||||
if ((res->Data.Address16.MinAddressFixed == ACPI_ADDRESS_FIXED) &&
|
||||
(res->Data.Address16.MaxAddressFixed == ACPI_ADDRESS_FIXED)) {
|
||||
if (res->Data.Address16.MinAddressFixed == ACPI_ADDRESS_FIXED &&
|
||||
res->Data.Address16.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
|
||||
|
||||
if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address16/Memory 0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address16/Memory 0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
set->set_memory(dev, context,
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address16/IO 0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address16/IO 0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
set->set_ioport(dev, context,
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.AddressLength);
|
||||
}
|
||||
} else {
|
||||
if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address16/Memory 0x%x-0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address16/Memory 0x%x-0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
set->set_memoryrange(dev, context,
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
res->Data.Address16.AddressLength,
|
||||
res->Data.Address16.Granularity);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Address16/IO 0x%x-0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"Address16/IO 0x%x-0x%x/%d\n",
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
res->Data.Address16.AddressLength));
|
||||
set->set_iorange(dev, context,
|
||||
res->Data.Address16.MinAddressRange,
|
||||
res->Data.Address16.MaxAddressRange,
|
||||
@ -345,27 +343,27 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_ADDRESS64:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "unimplemented Address64 resource\n"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"unimplemented Address64 resource\n"));
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_EXT_IRQ:
|
||||
/* XXX special handling? */
|
||||
set->set_irq(dev, context,res->Data.ExtendedIrq.Interrupts,
|
||||
res->Data.ExtendedIrq.NumberOfInterrupts);
|
||||
break;
|
||||
|
||||
case ACPI_RSTYPE_VENDOR:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "unimplemented VendorSpecific resource\n"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
|
||||
"unimplemented VendorSpecific resource\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AcpiOsFree(buf.Pointer);
|
||||
set->set_done(dev, context);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -374,17 +372,22 @@ acpi_parse_resources(device_t dev, ACPI_HANDLE handle, struct acpi_parse_resourc
|
||||
*/
|
||||
static void acpi_res_set_init(device_t dev, void **context);
|
||||
static void acpi_res_set_done(device_t dev, void *context);
|
||||
static void acpi_res_set_ioport(device_t dev, void *context, u_int32_t base, u_int32_t length);
|
||||
static void acpi_res_set_iorange(device_t dev, void *context, u_int32_t low, u_int32_t high,
|
||||
static void acpi_res_set_ioport(device_t dev, void *context,
|
||||
u_int32_t base, u_int32_t length);
|
||||
static void acpi_res_set_iorange(device_t dev, void *context,
|
||||
u_int32_t low, u_int32_t high,
|
||||
u_int32_t length, u_int32_t align);
|
||||
static void acpi_res_set_memory(device_t dev, void *context, u_int32_t base, u_int32_t length);
|
||||
static void acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low, u_int32_t high,
|
||||
static void acpi_res_set_memory(device_t dev, void *context,
|
||||
u_int32_t base, u_int32_t length);
|
||||
static void acpi_res_set_memoryrange(device_t dev, void *context,
|
||||
u_int32_t low, u_int32_t high,
|
||||
u_int32_t length, u_int32_t align);
|
||||
static void acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq,
|
||||
int count);
|
||||
static void acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq,
|
||||
int count);
|
||||
static void acpi_res_set_start_dependant(device_t dev, void *context, int preference);
|
||||
static void acpi_res_set_start_dependant(device_t dev, void *context,
|
||||
int preference);
|
||||
static void acpi_res_set_end_dependant(device_t dev, void *context);
|
||||
|
||||
struct acpi_parse_resource_set acpi_res_parse_set = {
|
||||
@ -429,7 +432,8 @@ acpi_res_set_done(device_t dev, void *context)
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_res_set_ioport(device_t dev, void *context, u_int32_t base, u_int32_t length)
|
||||
acpi_res_set_ioport(device_t dev, void *context, u_int32_t base,
|
||||
u_int32_t length)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
@ -439,7 +443,8 @@ acpi_res_set_ioport(device_t dev, void *context, u_int32_t base, u_int32_t lengt
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_res_set_iorange(device_t dev, void *context, u_int32_t low, u_int32_t high, u_int32_t length, u_int32_t align)
|
||||
acpi_res_set_iorange(device_t dev, void *context, u_int32_t low,
|
||||
u_int32_t high, u_int32_t length, u_int32_t align)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
@ -449,7 +454,8 @@ acpi_res_set_iorange(device_t dev, void *context, u_int32_t low, u_int32_t high,
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_res_set_memory(device_t dev, void *context, u_int32_t base, u_int32_t length)
|
||||
acpi_res_set_memory(device_t dev, void *context, u_int32_t base,
|
||||
u_int32_t length)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
@ -460,7 +466,8 @@ acpi_res_set_memory(device_t dev, void *context, u_int32_t base, u_int32_t lengt
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low, u_int32_t high, u_int32_t length, u_int32_t align)
|
||||
acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low,
|
||||
u_int32_t high, u_int32_t length, u_int32_t align)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
@ -474,13 +481,11 @@ acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq, int count)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
if (cp == NULL)
|
||||
return;
|
||||
if (irq == NULL)
|
||||
if (cp == NULL || irq == NULL)
|
||||
return;
|
||||
|
||||
/*This implements no resource relocation.*/
|
||||
if(count != 1)
|
||||
/* This implements no resource relocation. */
|
||||
if (count != 1)
|
||||
return;
|
||||
|
||||
bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1);
|
||||
@ -491,13 +496,11 @@ acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq, int count)
|
||||
{
|
||||
struct acpi_res_context *cp = (struct acpi_res_context *)context;
|
||||
|
||||
if (cp == NULL)
|
||||
return;
|
||||
if (drq == NULL)
|
||||
if (cp == NULL || drq == NULL)
|
||||
return;
|
||||
|
||||
/*This implements no resource relocation.*/
|
||||
if(count != 1)
|
||||
/* This implements no resource relocation. */
|
||||
if (count != 1)
|
||||
return;
|
||||
|
||||
bus_set_resource(dev, SYS_RES_DRQ, cp->ar_ndrq++, *drq, 1);
|
||||
@ -520,6 +523,7 @@ acpi_res_set_end_dependant(device_t dev, void *context)
|
||||
|
||||
if (cp == NULL)
|
||||
return;
|
||||
device_printf(dev, "dependant functions not supported\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -553,20 +557,19 @@ static driver_t acpi_sysresource_driver = {
|
||||
};
|
||||
|
||||
static devclass_t acpi_sysresource_devclass;
|
||||
DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver, acpi_sysresource_devclass, 0, 0);
|
||||
DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver,
|
||||
acpi_sysresource_devclass, 0, 0);
|
||||
|
||||
static int
|
||||
acpi_sysresource_probe(device_t dev)
|
||||
{
|
||||
if (acpi_disabled("sysresource"))
|
||||
return(ENXIO);
|
||||
if (acpi_MatchHid(dev, "PNP0C02")) {
|
||||
if (!acpi_disabled("sysresource") && acpi_MatchHid(dev, "PNP0C02"))
|
||||
device_set_desc(dev, "system resource");
|
||||
} else {
|
||||
return(ENXIO);
|
||||
}
|
||||
else
|
||||
return (ENXIO);
|
||||
|
||||
device_quiet(dev);
|
||||
return(-100);
|
||||
return (-100);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -587,7 +590,9 @@ acpi_sysresource_attach(device_t dev)
|
||||
rid = i;
|
||||
res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, 0);
|
||||
rid = i;
|
||||
res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE);
|
||||
res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE);
|
||||
}
|
||||
return(0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -40,12 +40,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/power.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_THERMAL
|
||||
ACPI_MODULE_NAME("THERMAL")
|
||||
|
||||
@ -56,9 +53,11 @@ ACPI_MODULE_NAME("THERMAL")
|
||||
#define TZ_NOTIFY_DEVICES 0x81
|
||||
#define TZ_NOTIFY_LEVELS 0x82
|
||||
|
||||
#define TZ_POLLRATE 30 /* every 30 seconds by default */
|
||||
/* Check for temperature changes every 30 seconds by default */
|
||||
#define TZ_POLLRATE 30
|
||||
|
||||
#define TZ_NUMLEVELS 10 /* defined by ACPI spec */
|
||||
/* ACPI spec defines this */
|
||||
#define TZ_NUMLEVELS 10
|
||||
struct acpi_tz_zone {
|
||||
int ac[TZ_NUMLEVELS];
|
||||
ACPI_BUFFER al[TZ_NUMLEVELS];
|
||||
@ -74,45 +73,46 @@ struct acpi_tz_zone {
|
||||
|
||||
|
||||
struct acpi_tz_softc {
|
||||
device_t tz_dev; /* device handle */
|
||||
ACPI_HANDLE tz_handle; /* thermal zone handle */
|
||||
int tz_temperature; /* current temperature */
|
||||
int tz_active; /* current active cooling */
|
||||
device_t tz_dev;
|
||||
ACPI_HANDLE tz_handle; /*Thermal zone handle*/
|
||||
int tz_temperature; /*Current temperature*/
|
||||
int tz_active; /*Current active cooling*/
|
||||
#define TZ_ACTIVE_NONE -1
|
||||
int tz_requested; /* user-requested minimum active cooling */
|
||||
int tz_thflags; /* current temperature-related flags */
|
||||
int tz_requested; /*Minimum active cooling*/
|
||||
int tz_thflags; /*Current temp-related flags*/
|
||||
#define TZ_THFLAG_NONE 0
|
||||
#define TZ_THFLAG_PSV (1<<0)
|
||||
#define TZ_THFLAG_HOT (1<<2)
|
||||
#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 power_profile in timeout */
|
||||
struct timespec tz_cooling_started; /* current cooling starting time */
|
||||
#define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/
|
||||
#define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/
|
||||
struct timespec tz_cooling_started;
|
||||
/*Current cooling starting time*/
|
||||
|
||||
struct sysctl_ctx_list tz_sysctl_ctx; /* sysctl tree */
|
||||
struct sysctl_ctx_list tz_sysctl_ctx;
|
||||
struct sysctl_oid *tz_sysctl_tree;
|
||||
|
||||
struct acpi_tz_zone tz_zone; /* thermal zone parameters */
|
||||
struct acpi_tz_zone tz_zone; /*Thermal zone parameters*/
|
||||
int tz_tmp_updating;
|
||||
};
|
||||
|
||||
static int acpi_tz_probe(device_t dev);
|
||||
static int acpi_tz_attach(device_t dev);
|
||||
static int acpi_tz_establish(struct acpi_tz_softc *sc);
|
||||
static void acpi_tz_monitor(struct acpi_tz_softc *sc);
|
||||
static void acpi_tz_monitor(void *Context);
|
||||
static void acpi_tz_all_off(struct acpi_tz_softc *sc);
|
||||
static void acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg);
|
||||
static void acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg);
|
||||
static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data);
|
||||
static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node,
|
||||
int *data);
|
||||
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_notify_handler(ACPI_HANDLE h, UINT32 notify,
|
||||
void *context);
|
||||
static void acpi_tz_timeout(struct acpi_tz_softc *sc);
|
||||
static void acpi_tz_power_profile(void *arg);
|
||||
|
||||
static void acpi_tz_thread(void *arg);
|
||||
static struct proc *acpi_tz_proc;
|
||||
|
||||
static device_method_t acpi_tz_methods[] = {
|
||||
/* Device interface */
|
||||
@ -134,9 +134,13 @@ DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, 0, 0);
|
||||
static struct sysctl_ctx_list acpi_tz_sysctl_ctx;
|
||||
static struct sysctl_oid *acpi_tz_sysctl_tree;
|
||||
|
||||
static int acpi_tz_min_runtime = 0;/* minimum cooling run time */
|
||||
/* Minimum cooling run time */
|
||||
static int acpi_tz_min_runtime = 0;
|
||||
static int acpi_tz_polling_rate = TZ_POLLRATE;
|
||||
|
||||
/* Timezone polling thread */
|
||||
static struct proc *acpi_tz_proc;
|
||||
|
||||
/*
|
||||
* Match an ACPI thermal zone.
|
||||
*/
|
||||
@ -148,17 +152,16 @@ acpi_tz_probe(device_t dev)
|
||||
|
||||
ACPI_LOCK;
|
||||
|
||||
/* no FUNCTION_TRACE - too noisy */
|
||||
/* No FUNCTION_TRACE - too noisy */
|
||||
|
||||
if ((acpi_get_type(dev) == ACPI_TYPE_THERMAL) &&
|
||||
!acpi_disabled("thermal")) {
|
||||
if (acpi_get_type(dev) == ACPI_TYPE_THERMAL && !acpi_disabled("thermal")) {
|
||||
device_set_desc(dev, "thermal zone");
|
||||
result = -10;
|
||||
} else {
|
||||
result = ENXIO;
|
||||
}
|
||||
ACPI_UNLOCK;
|
||||
return(result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -205,12 +208,13 @@ acpi_tz_attach(device_t dev)
|
||||
acpi_sc = acpi_device_get_parent_softc(dev);
|
||||
sysctl_ctx_init(&acpi_tz_sysctl_ctx);
|
||||
acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
|
||||
OID_AUTO, "thermal", CTLFLAG_RD, 0, "");
|
||||
SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
|
||||
OID_AUTO, "thermal", CTLFLAG_RD, 0, "");
|
||||
SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
|
||||
OID_AUTO, "min_runtime", CTLFLAG_RD | CTLFLAG_RW,
|
||||
&acpi_tz_min_runtime, 0, "minimum cooling run time in sec");
|
||||
&acpi_tz_min_runtime, 0,
|
||||
"minimum cooling run time in sec");
|
||||
SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
|
||||
OID_AUTO, "polling_rate", CTLFLAG_RD | CTLFLAG_RW,
|
||||
@ -219,8 +223,8 @@ acpi_tz_attach(device_t dev)
|
||||
sysctl_ctx_init(&sc->tz_sysctl_ctx);
|
||||
sprintf(oidname, "tz%d", device_get_unit(dev));
|
||||
sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO,
|
||||
oidname, CTLFLAG_RD, 0, "");
|
||||
SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
|
||||
OID_AUTO, oidname, CTLFLAG_RD, 0, "");
|
||||
SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
|
||||
OID_AUTO, "temperature", CTLFLAG_RD,
|
||||
&sc->tz_temperature, 0, "current thermal zone temperature");
|
||||
@ -244,7 +248,6 @@ acpi_tz_attach(device_t dev)
|
||||
OID_AUTO, "_ACx", CTLFLAG_RD, &sc->tz_zone.ac,
|
||||
sizeof(sc->tz_zone.ac), "I", "");
|
||||
|
||||
|
||||
/*
|
||||
* Register our power profile event handler, and flag it for a manual
|
||||
* invocation by our timeout. We defer it like this so that the rest
|
||||
@ -266,7 +269,8 @@ acpi_tz_attach(device_t dev)
|
||||
error = kthread_create(acpi_tz_thread, NULL, &acpi_tz_proc,
|
||||
RFHIGHPID, 0, "acpi_thermal");
|
||||
if (error != 0) {
|
||||
device_printf(sc->tz_dev, "could not create thread - %d", error);
|
||||
device_printf(sc->tz_dev, "could not create thread - %d",
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -274,7 +278,7 @@ acpi_tz_attach(device_t dev)
|
||||
out:
|
||||
ACPI_UNLOCK;
|
||||
|
||||
return_VALUE(error);
|
||||
return_VALUE (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -293,9 +297,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
||||
|
||||
ACPI_ASSERTLOCK;
|
||||
|
||||
/*
|
||||
* Power everything off and erase any existing state.
|
||||
*/
|
||||
/* Power everything off and erase any existing state. */
|
||||
acpi_tz_all_off(sc);
|
||||
for (i = 0; i < TZ_NUMLEVELS; i++)
|
||||
if (sc->tz_zone.al[i].Pointer != NULL)
|
||||
@ -304,9 +306,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
||||
AcpiOsFree(sc->tz_zone.psl.Pointer);
|
||||
bzero(&sc->tz_zone, sizeof(sc->tz_zone));
|
||||
|
||||
/*
|
||||
* Evaluate thermal zone parameters.
|
||||
*/
|
||||
/* Evaluate thermal zone parameters. */
|
||||
for (i = 0; i < TZ_NUMLEVELS; i++) {
|
||||
sprintf(nbuf, "_AC%d", i);
|
||||
acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]);
|
||||
@ -316,11 +316,11 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
||||
AcpiEvaluateObject(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]);
|
||||
obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer;
|
||||
if (obj != NULL) {
|
||||
/* should be a package containing a list of power objects */
|
||||
/* Should be a package containing a list of power objects */
|
||||
if (obj->Type != ACPI_TYPE_PACKAGE) {
|
||||
device_printf(sc->tz_dev, "%s has unknown object type %d, rejecting\n",
|
||||
device_printf(sc->tz_dev, "%s has unknown type %d, rejecting\n",
|
||||
nbuf, obj->Type);
|
||||
return_VALUE(ENXIO);
|
||||
return_VALUE (ENXIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,7 +352,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
||||
*/
|
||||
acpi_tz_all_off(sc);
|
||||
|
||||
return_VALUE(0);
|
||||
return_VALUE (0);
|
||||
}
|
||||
|
||||
static char *aclevel_string[] = {
|
||||
@ -362,9 +362,8 @@ static char *aclevel_string[] = {
|
||||
static __inline const char *
|
||||
acpi_tz_aclevel_string(int active)
|
||||
{
|
||||
if (active < -1 || active >= TZ_NUMLEVELS) {
|
||||
if (active < -1 || active >= TZ_NUMLEVELS)
|
||||
return (aclevel_string[0]);
|
||||
}
|
||||
|
||||
return (aclevel_string[active+1]);
|
||||
}
|
||||
@ -373,27 +372,27 @@ acpi_tz_aclevel_string(int active)
|
||||
* Evaluate the condition of a thermal zone, take appropriate actions.
|
||||
*/
|
||||
static void
|
||||
acpi_tz_monitor(struct acpi_tz_softc *sc)
|
||||
acpi_tz_monitor(void *Context)
|
||||
{
|
||||
struct acpi_tz_softc *sc;
|
||||
struct timespec curtime;
|
||||
int temp;
|
||||
int i;
|
||||
int newactive, newflags;
|
||||
struct timespec curtime;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
ACPI_ASSERTLOCK;
|
||||
|
||||
if (sc->tz_tmp_updating) {
|
||||
sc = (struct acpi_tz_softc *)Context;
|
||||
if (sc->tz_tmp_updating)
|
||||
goto out;
|
||||
}
|
||||
sc->tz_tmp_updating = 1;
|
||||
|
||||
/*
|
||||
* Get the current temperature.
|
||||
*/
|
||||
if (ACPI_FAILURE(status = acpi_EvaluateInteger(sc->tz_handle, "_TMP", &temp))) {
|
||||
/* Get the current temperature. */
|
||||
status = acpi_EvaluateInteger(sc->tz_handle, "_TMP", &temp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"error fetching current temperature -- %s\n",
|
||||
AcpiFormatException(status));
|
||||
@ -414,9 +413,10 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
|
||||
if ((sc->tz_zone.ac[i] != -1) && (temp >= sc->tz_zone.ac[i])) {
|
||||
newactive = i;
|
||||
if (sc->tz_active != newactive) {
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"_AC%d: temperature %d.%d >= setpoint %d.%d\n", i,
|
||||
TZ_KELVTOC(temp), TZ_KELVTOC(sc->tz_zone.ac[i]));
|
||||
ACPI_VPRINT(sc->tz_dev,
|
||||
acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"_AC%d: temperature %d.%d >= setpoint %d.%d\n", i,
|
||||
TZ_KELVTOC(temp), TZ_KELVTOC(sc->tz_zone.ac[i]));
|
||||
getnanotime(&sc->tz_cooling_started);
|
||||
}
|
||||
}
|
||||
@ -428,14 +428,14 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
|
||||
*/
|
||||
if (acpi_tz_min_runtime > 0 && sc->tz_active != TZ_ACTIVE_NONE &&
|
||||
(newactive == TZ_ACTIVE_NONE || newactive > sc->tz_active)) {
|
||||
|
||||
getnanotime(&curtime);
|
||||
timespecsub(&curtime, &sc->tz_cooling_started);
|
||||
if (curtime.tv_sec < acpi_tz_min_runtime) {
|
||||
if (curtime.tv_sec < acpi_tz_min_runtime)
|
||||
newactive = sc->tz_active;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle user override of active mode */
|
||||
/* Handle user override of active mode */
|
||||
if (sc->tz_requested > newactive)
|
||||
newactive = sc->tz_requested;
|
||||
|
||||
@ -448,30 +448,28 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
|
||||
if ((sc->tz_zone.crt != -1) && (temp >= sc->tz_zone.crt))
|
||||
newflags |= TZ_THFLAG_CRT;
|
||||
|
||||
/*
|
||||
* If the active cooling state has changed, we have to switch things.
|
||||
*/
|
||||
/* If the active cooling state has changed, we have to switch things. */
|
||||
if (newactive != sc->tz_active) {
|
||||
|
||||
/* turn off the cooling devices that are on, if any are */
|
||||
/* Turn off the cooling devices that are on, if any are */
|
||||
if (sc->tz_active != TZ_ACTIVE_NONE)
|
||||
acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[sc->tz_active].Pointer,
|
||||
acpi_tz_switch_cooler_off, sc);
|
||||
acpi_ForeachPackageObject(
|
||||
(ACPI_OBJECT *)sc->tz_zone.al[sc->tz_active].Pointer,
|
||||
acpi_tz_switch_cooler_off, sc);
|
||||
|
||||
/* turn on cooling devices that are required, if any are */
|
||||
if (newactive != TZ_ACTIVE_NONE)
|
||||
acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[newactive].Pointer,
|
||||
acpi_tz_switch_cooler_on, sc);
|
||||
/* Turn on cooling devices that are required, if any are */
|
||||
if (newactive != TZ_ACTIVE_NONE) {
|
||||
acpi_ForeachPackageObject(
|
||||
(ACPI_OBJECT *)sc->tz_zone.al[newactive].Pointer,
|
||||
acpi_tz_switch_cooler_on, sc);
|
||||
}
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"switched from %s to %s: %d.%dC\n",
|
||||
acpi_tz_aclevel_string(sc->tz_active),
|
||||
acpi_tz_aclevel_string(newactive), TZ_KELVTOC(temp));
|
||||
"switched from %s to %s: %d.%dC\n",
|
||||
acpi_tz_aclevel_string(sc->tz_active),
|
||||
acpi_tz_aclevel_string(newactive), TZ_KELVTOC(temp));
|
||||
sc->tz_active = newactive;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX (de)activate any passive cooling that may be required.
|
||||
*/
|
||||
/* XXX (de)activate any passive cooling that may be required. */
|
||||
|
||||
/*
|
||||
* If we have just become _HOT or _CRT, warn the user.
|
||||
@ -479,9 +477,11 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
|
||||
* We should actually shut down at this point, but it's not clear
|
||||
* that some systems don't actually map _CRT to the same value as _AC0.
|
||||
*/
|
||||
if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) &&
|
||||
!(sc->tz_thflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT))) {
|
||||
device_printf(sc->tz_dev, "WARNING - current temperature (%d.%dC) exceeds system limits\n",
|
||||
if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0 &&
|
||||
(sc->tz_thflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) == 0) {
|
||||
|
||||
device_printf(sc->tz_dev,
|
||||
"WARNING - current temperature (%d.%dC) exceeds system limits\n",
|
||||
TZ_KELVTOC(sc->tz_temperature));
|
||||
/* shutdown_nice(RB_POWEROFF);*/
|
||||
}
|
||||
@ -504,9 +504,7 @@ acpi_tz_all_off(struct acpi_tz_softc *sc)
|
||||
|
||||
ACPI_ASSERTLOCK;
|
||||
|
||||
/*
|
||||
* Scan all the _ALx objects, and turn them all off.
|
||||
*/
|
||||
/* Scan all the _ALx objects and turn them all off. */
|
||||
for (i = 0; i < TZ_NUMLEVELS; i++) {
|
||||
if (sc->tz_zone.al[i].Pointer == NULL)
|
||||
continue;
|
||||
@ -520,6 +518,7 @@ acpi_tz_all_off(struct acpi_tz_softc *sc)
|
||||
|
||||
sc->tz_active = TZ_ACTIVE_NONE;
|
||||
sc->tz_thflags = TZ_THFLAG_NONE;
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
@ -538,13 +537,14 @@ acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg)
|
||||
|
||||
switch(obj->Type) {
|
||||
case ACPI_TYPE_ANY:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", acpi_name(obj->Reference.Handle)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n",
|
||||
acpi_name(obj->Reference.Handle)));
|
||||
|
||||
acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D3);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", obj->String.Pointer));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n",
|
||||
obj->String.Pointer));
|
||||
|
||||
/*
|
||||
* Find the handle for the device and turn it off.
|
||||
@ -556,12 +556,13 @@ acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg)
|
||||
if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler)))
|
||||
acpi_pwr_switch_consumer(cooler, ACPI_STATE_D3);
|
||||
break;
|
||||
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to handle unsupported object type %d\n",
|
||||
obj->Type));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
|
||||
"called to handle unsupported object type %d\n",
|
||||
obj->Type));
|
||||
break;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
@ -584,17 +585,20 @@ acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg)
|
||||
|
||||
switch(obj->Type) {
|
||||
case ACPI_TYPE_ANY:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", acpi_name(obj->Reference.Handle)));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n",
|
||||
acpi_name(obj->Reference.Handle)));
|
||||
|
||||
if (ACPI_FAILURE(status = acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D0))) {
|
||||
status = acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D0);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"failed to activate %s - %s\n", acpi_name(obj->Reference.Handle),
|
||||
AcpiFormatException(status));
|
||||
"failed to activate %s - %s\n",
|
||||
acpi_name(obj->Reference.Handle),
|
||||
AcpiFormatException(status));
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", obj->String.Pointer));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n",
|
||||
obj->String.Pointer));
|
||||
|
||||
/*
|
||||
* Find the handle for the device and turn it off.
|
||||
@ -604,23 +608,25 @@ acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg)
|
||||
* XXX This may not always be the case.
|
||||
*/
|
||||
if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler))) {
|
||||
if (ACPI_FAILURE(status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0))) {
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"failed to activate %s - %s\n",
|
||||
obj->String.Pointer, AcpiFormatException(status));
|
||||
status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_VPRINT(sc->tz_dev,
|
||||
acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"failed to activate %s - %s\n",
|
||||
obj->String.Pointer, AcpiFormatException(status));
|
||||
}
|
||||
} else {
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"couldn't find %s\n", obj->String.Pointer);
|
||||
"couldn't find %s\n", obj->String.Pointer);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to handle unsupported object type %d\n",
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "unsupported object type %d\n",
|
||||
obj->Type));
|
||||
break;
|
||||
}
|
||||
return_VOID;
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -637,9 +643,10 @@ acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data)
|
||||
if (ACPI_FAILURE(acpi_EvaluateInteger(sc->tz_handle, node, data))) {
|
||||
*data = -1;
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", acpi_name(sc->tz_handle),
|
||||
node, *data));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n",
|
||||
acpi_name(sc->tz_handle), node, *data));
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
@ -650,7 +657,7 @@ acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data)
|
||||
static void
|
||||
acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what)
|
||||
{
|
||||
if ((*val != -1) && ((*val < TZ_ZEROC) || (*val > (TZ_ZEROC + 1500)))) {
|
||||
if (*val != -1 && (*val < TZ_ZEROC || *val > TZ_ZEROC + 1500)) {
|
||||
device_printf(sc->tz_dev, "%s value is absurd, ignored (%d.%dC)\n",
|
||||
what, TZ_KELVTOC(*val));
|
||||
*val = -1;
|
||||
@ -674,23 +681,21 @@ acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
active = sc->tz_active;
|
||||
error = sysctl_handle_int(oidp, &active, 0, req);
|
||||
|
||||
/* error or no new value */
|
||||
if ((error != 0) || (req->newptr == NULL))
|
||||
/* Error or no new value */
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
goto out;
|
||||
|
||||
/* range check */
|
||||
if ((active < -1) || (active >= TZ_NUMLEVELS)) {
|
||||
if (active < -1 || active >= TZ_NUMLEVELS) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* set new preferred level and re-switch */
|
||||
/* Set new preferred level and re-switch */
|
||||
sc->tz_requested = active;
|
||||
acpi_tz_monitor(sc);
|
||||
|
||||
out:
|
||||
ACPI_UNLOCK;
|
||||
return(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -707,19 +712,21 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
|
||||
switch(notify) {
|
||||
case TZ_NOTIFY_TEMPERATURE:
|
||||
/* temperature change occurred */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_monitor, sc);
|
||||
/* Temperature change occurred */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, acpi_tz_monitor, sc);
|
||||
break;
|
||||
case TZ_NOTIFY_DEVICES:
|
||||
case TZ_NOTIFY_LEVELS:
|
||||
/* zone devices/setpoints changed */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc);
|
||||
/* Zone devices/setpoints changed */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
|
||||
(OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc);
|
||||
break;
|
||||
default:
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"unknown Notify event 0x%x\n", notify);
|
||||
"unknown Notify event 0x%x\n", notify);
|
||||
break;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
@ -729,8 +736,7 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
static void
|
||||
acpi_tz_timeout(struct acpi_tz_softc *sc)
|
||||
{
|
||||
|
||||
/* do we need to get the power profile settings? */
|
||||
/* Do we need to get the power profile settings? */
|
||||
if (sc->tz_flags & TZ_FLAG_GETPROFILE) {
|
||||
acpi_tz_power_profile((void *)sc);
|
||||
sc->tz_flags &= ~TZ_FLAG_GETPROFILE;
|
||||
@ -738,7 +744,7 @@ acpi_tz_timeout(struct acpi_tz_softc *sc)
|
||||
|
||||
ACPI_ASSERTLOCK;
|
||||
|
||||
/* check the current temperature and take action based on it */
|
||||
/* Check the current temperature and take action based on it */
|
||||
acpi_tz_monitor(sc);
|
||||
|
||||
/* XXX passive cooling actions? */
|
||||
@ -762,32 +768,36 @@ acpi_tz_power_profile(void *arg)
|
||||
ACPI_LOCK_DECL;
|
||||
|
||||
state = power_profile_get_state();
|
||||
if (state != POWER_PROFILE_PERFORMANCE &&
|
||||
state != POWER_PROFILE_ECONOMY) {
|
||||
return;
|
||||
}
|
||||
if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY)
|
||||
return;
|
||||
|
||||
ACPI_LOCK;
|
||||
|
||||
/* check that we haven't decided there's no _SCP method */
|
||||
if (!(sc->tz_flags & TZ_FLAG_NO_SCP)) {
|
||||
if ((sc->tz_flags & TZ_FLAG_NO_SCP) == 0) {
|
||||
|
||||
/* call _SCP to set the new profile */
|
||||
/* Call _SCP to set the new profile */
|
||||
obj.Type = ACPI_TYPE_INTEGER;
|
||||
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))) {
|
||||
status = AcpiEvaluateObject(sc->tz_handle, "_SCP", &args, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status != AE_NOT_FOUND)
|
||||
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"can't evaluate %s._SCP - %s\n", acpi_name(sc->tz_handle),
|
||||
AcpiFormatException(status));
|
||||
ACPI_VPRINT(sc->tz_dev,
|
||||
acpi_device_get_parent_softc(sc->tz_dev),
|
||||
"can't evaluate %s._SCP - %s\n",
|
||||
acpi_name(sc->tz_handle),
|
||||
AcpiFormatException(status));
|
||||
sc->tz_flags |= TZ_FLAG_NO_SCP;
|
||||
} else {
|
||||
/* we have to re-evaluate the entire zone now */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc);
|
||||
/* We have to re-evaluate the entire zone now */
|
||||
AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
|
||||
(OSD_EXECUTION_CALLBACK)acpi_tz_establish,
|
||||
sc);
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_UNLOCK;
|
||||
}
|
||||
|
||||
@ -803,12 +813,11 @@ acpi_tz_thread(void *arg)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
|
||||
devs = NULL;
|
||||
devcount = 0;
|
||||
|
||||
for (;;) {
|
||||
tsleep(&acpi_tz_proc, PZERO, "nothing", hz * acpi_tz_polling_rate);
|
||||
tsleep(&acpi_tz_proc, PZERO, "tzpoll", hz * acpi_tz_polling_rate);
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
mtx_lock(&Giant);
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
@ -52,16 +51,14 @@
|
||||
* Based on the i386-only mp_clock.c by <phk@FreeBSD.ORG>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hooks for the ACPI CA debugging infrastructure
|
||||
*/
|
||||
/* Hooks for the ACPI CA debugging infrastructure */
|
||||
#define _COMPONENT ACPI_SYSTEM
|
||||
ACPI_MODULE_NAME("TIMER")
|
||||
|
||||
static device_t acpi_timer_dev;
|
||||
struct resource *acpi_timer_reg;
|
||||
|
||||
static u_int acpi_timer_frequency = 14318182/4;
|
||||
static u_int acpi_timer_frequency = 14318182 / 4;
|
||||
|
||||
static void acpi_timer_identify(driver_t *driver, device_t parent);
|
||||
static int acpi_timer_probe(device_t dev);
|
||||
@ -71,12 +68,9 @@ static unsigned acpi_timer_get_timecount_safe(struct timecounter *tc);
|
||||
static int acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS);
|
||||
static void acpi_timer_test(void);
|
||||
|
||||
static u_int32_t read_counter(void);
|
||||
static int test_counter(void);
|
||||
static uint32_t read_counter(void);
|
||||
static int test_counter(void);
|
||||
|
||||
/*
|
||||
* Driver hung off ACPI.
|
||||
*/
|
||||
static device_method_t acpi_timer_methods[] = {
|
||||
DEVMETHOD(device_identify, acpi_timer_identify),
|
||||
DEVMETHOD(device_probe, acpi_timer_probe),
|
||||
@ -94,9 +88,6 @@ static driver_t acpi_timer_driver = {
|
||||
static devclass_t acpi_timer_devclass;
|
||||
DRIVER_MODULE(acpi_timer, acpi, acpi_timer_driver, acpi_timer_devclass, 0, 0);
|
||||
|
||||
/*
|
||||
* Timecounter.
|
||||
*/
|
||||
static struct timecounter acpi_timer_timecounter = {
|
||||
acpi_timer_get_timecount_safe,
|
||||
0,
|
||||
@ -106,52 +97,55 @@ static struct timecounter acpi_timer_timecounter = {
|
||||
1000
|
||||
};
|
||||
|
||||
|
||||
static u_int32_t
|
||||
static uint32_t
|
||||
read_counter()
|
||||
{
|
||||
bus_space_handle_t bsh;
|
||||
bus_space_tag_t bst;
|
||||
u_int32_t tv;
|
||||
bus_space_handle_t bsh;
|
||||
bus_space_tag_t bst;
|
||||
u_int32_t tv;
|
||||
|
||||
bsh = rman_get_bushandle(acpi_timer_reg);
|
||||
bst = rman_get_bustag(acpi_timer_reg);
|
||||
tv = bus_space_read_4(bst, bsh, 0);
|
||||
bus_space_barrier(bst, bsh, 0, 4, BUS_SPACE_BARRIER_READ);
|
||||
return (tv);
|
||||
bsh = rman_get_bushandle(acpi_timer_reg);
|
||||
bst = rman_get_bustag(acpi_timer_reg);
|
||||
tv = bus_space_read_4(bst, bsh, 0);
|
||||
bus_space_barrier(bst, bsh, 0, 4, BUS_SPACE_BARRIER_READ);
|
||||
|
||||
return (tv);
|
||||
}
|
||||
|
||||
#define N 2000
|
||||
static int
|
||||
test_counter()
|
||||
{
|
||||
int min, max, n, delta;
|
||||
unsigned last, this;
|
||||
u_int last, this;
|
||||
int min, max, n, delta;
|
||||
|
||||
min = 10000000;
|
||||
max = 0;
|
||||
last = read_counter();
|
||||
for (n = 0; n < N; n++) {
|
||||
this = read_counter();
|
||||
delta = (this - last) & 0xffffff;
|
||||
if (delta > max)
|
||||
max = delta;
|
||||
else if (delta < min)
|
||||
min = delta;
|
||||
last = this;
|
||||
}
|
||||
if (max - min > 2)
|
||||
n = 0;
|
||||
else if (min < 0 || max == 0)
|
||||
n = 0;
|
||||
else
|
||||
n = 1;
|
||||
if (bootverbose)
|
||||
printf("ACPI timer looks %s min = %d, max = %d, width = %d\n",
|
||||
n ? "GOOD" : "BAD ",
|
||||
min, max, max - min);
|
||||
return (n);
|
||||
min = 10000000;
|
||||
max = 0;
|
||||
last = read_counter();
|
||||
for (n = 0; n < N; n++) {
|
||||
this = read_counter();
|
||||
delta = (this - last) & 0xffffff;
|
||||
if (delta > max)
|
||||
max = delta;
|
||||
else if (delta < min)
|
||||
min = delta;
|
||||
last = this;
|
||||
}
|
||||
if (max - min > 2)
|
||||
n = 0;
|
||||
else if (min < 0 || max == 0)
|
||||
n = 0;
|
||||
else
|
||||
n = 1;
|
||||
if (bootverbose) {
|
||||
printf("ACPI timer looks %s min = %d, max = %d, width = %d\n",
|
||||
n ? "GOOD" : "BAD ",
|
||||
min, max, max - min);
|
||||
}
|
||||
|
||||
return (n);
|
||||
}
|
||||
#undef N
|
||||
|
||||
/*
|
||||
* Locate the ACPI timer using the FADT, set up and allocate the I/O resources
|
||||
@ -167,10 +161,7 @@ acpi_timer_identify(driver_t *driver, device_t parent)
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
if (acpi_disabled("timer"))
|
||||
return_VOID;
|
||||
|
||||
if (AcpiGbl_FADT == NULL)
|
||||
if (acpi_disabled("timer") || AcpiGbl_FADT == NULL)
|
||||
return_VOID;
|
||||
|
||||
if ((dev = BUS_ADD_CHILD(parent, 0, "acpi_timer", 0)) == NULL) {
|
||||
@ -188,7 +179,7 @@ acpi_timer_identify(driver_t *driver, device_t parent)
|
||||
acpi_timer_reg = bus_alloc_resource(dev, rtype, &rid, 0, ~0, 1, RF_ACTIVE);
|
||||
if (acpi_timer_reg == NULL) {
|
||||
device_printf(dev, "couldn't allocate I/O resource (%s 0x%lx)\n",
|
||||
(rtype == SYS_RES_IOPORT) ? "port" : "mem", rstart);
|
||||
rtype == SYS_RES_IOPORT ? "port" : "mem", rstart);
|
||||
return_VOID;
|
||||
}
|
||||
if (testenv("debug.acpi.timer_test"))
|
||||
@ -207,8 +198,8 @@ acpi_timer_identify(driver_t *driver, device_t parent)
|
||||
}
|
||||
tc_init(&acpi_timer_timecounter);
|
||||
|
||||
sprintf(desc, "%d-bit timer at 3.579545MHz", (AcpiGbl_FADT->TmrValExt)
|
||||
? 32 : 24);
|
||||
sprintf(desc, "%d-bit timer at 3.579545MHz",
|
||||
AcpiGbl_FADT->TmrValExt ? 32 : 24);
|
||||
device_set_desc_copy(dev, desc);
|
||||
|
||||
return_VOID;
|
||||
@ -218,14 +209,15 @@ static int
|
||||
acpi_timer_probe(device_t dev)
|
||||
{
|
||||
if (dev == acpi_timer_dev)
|
||||
return(0);
|
||||
return(ENXIO);
|
||||
return (0);
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_timer_attach(device_t dev)
|
||||
{
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -252,7 +244,8 @@ acpi_timer_get_timecount_safe(struct timecounter *tc)
|
||||
u1 = u2;
|
||||
u2 = u3;
|
||||
u3 = read_counter();
|
||||
} while (u1 > u2 || u2 > u3 || (u3 - u1) > 15);
|
||||
} while (u1 > u2 || u2 > u3 || u3 - u1 > 15);
|
||||
|
||||
return (u2);
|
||||
}
|
||||
|
||||
@ -273,6 +266,7 @@ acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS)
|
||||
acpi_timer_frequency = freq;
|
||||
acpi_timer_timecounter.tc_frequency = acpi_timer_frequency;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -295,12 +289,13 @@ acpi_timer_test(void)
|
||||
device_printf(acpi_timer_dev, "timer test in progress, reboot to quit.\n");
|
||||
for (;;) {
|
||||
/*
|
||||
* The failure case is where u3 > u1, but u2 does not fall between the two,
|
||||
* ie. it contains garbage.
|
||||
* The failure case is where u3 > u1, but u2 does not fall between
|
||||
* the two, ie. it contains garbage.
|
||||
*/
|
||||
if (u3 > u1) {
|
||||
if ((u2 < u1) || (u2 > u3))
|
||||
device_printf(acpi_timer_dev, "timer is not monotonic: 0x%08x,0x%08x,0x%08x\n",
|
||||
if (u2 < u1 || u2 > u3)
|
||||
device_printf(acpi_timer_dev,
|
||||
"timer is not monotonic: 0x%08x,0x%08x,0x%08x\n",
|
||||
u1, u2, u3);
|
||||
}
|
||||
u1 = u2;
|
||||
@ -359,7 +354,8 @@ static driver_t acpi_timer_pci_driver = {
|
||||
};
|
||||
|
||||
devclass_t acpi_timer_pci_devclass;
|
||||
DRIVER_MODULE(acpi_timer_pci, pci, acpi_timer_pci_driver, acpi_timer_pci_devclass, 0, 0);
|
||||
DRIVER_MODULE(acpi_timer_pci, pci, acpi_timer_pci_driver,
|
||||
acpi_timer_pci_devclass, 0, 0);
|
||||
|
||||
/*
|
||||
* Look at PCI devices going past; if we detect one we know contains
|
||||
@ -375,16 +371,19 @@ acpi_timer_pci_probe(device_t dev)
|
||||
device = pci_get_device(dev);
|
||||
revid = pci_get_revid(dev);
|
||||
|
||||
if (((vendor == 0x8086) && (device == 0x7113) && (revid >= 0x03)) || /* PIIX4M */
|
||||
((vendor == 0x8086) && (device == 0x719b)) || /* i440MX */
|
||||
0) {
|
||||
/* Detect the PIIX4M and i440MX, respectively */
|
||||
if ((vendor == 0x8086 && device == 0x7113 && revid >= 0x03) ||
|
||||
(vendor == 0x8086 && device == 0x719b)) {
|
||||
|
||||
acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount;
|
||||
acpi_timer_timecounter.tc_name = "ACPI-fast";
|
||||
if (bootverbose)
|
||||
device_printf(acpi_timer_dev, "functional ACPI timer detected, enabling fast timecount interface\n");
|
||||
if (bootverbose) {
|
||||
device_printf(acpi_timer_dev,"functional ACPI timer detected, "
|
||||
"enabling fast timecount interface\n");
|
||||
}
|
||||
}
|
||||
|
||||
return(ENXIO); /* we never match anything */
|
||||
/* We never match anything */
|
||||
return (ENXIO);
|
||||
}
|
||||
#endif
|
||||
|
@ -35,41 +35,41 @@
|
||||
#define ACPIIO_SETSLPSTATE _IOW('P', 3, int)
|
||||
|
||||
struct acpi_battdesc {
|
||||
int type; /* battery type: e.g. CMBAT */
|
||||
int phys_unit; /* physical unit of devclass */
|
||||
int type; /* battery type: e.g. CMBAT */
|
||||
int phys_unit; /* physical unit of devclass */
|
||||
};
|
||||
|
||||
#define ACPI_BATT_TYPE_CMBAT 0x0000
|
||||
#define ACPI_BATT_TYPE_SMBAT 0x0001
|
||||
|
||||
struct acpi_battinfo {
|
||||
int cap; /* percent */
|
||||
int min; /* remianing time */
|
||||
int state; /* battery state */
|
||||
int cap; /* percent */
|
||||
int min; /* remianing time */
|
||||
int state; /* battery state */
|
||||
};
|
||||
|
||||
#define ACPI_CMBAT_MAXSTRLEN 32
|
||||
struct acpi_bif {
|
||||
u_int32_t unit; /* 0 for mWh, 1 for mAh */
|
||||
u_int32_t dcap; /* Design Capacity */
|
||||
u_int32_t lfcap; /* Last Full capacity */
|
||||
u_int32_t btech; /* Battery Technorogy */
|
||||
u_int32_t dvol; /* Design voltage (mV) */
|
||||
u_int32_t wcap; /* WARN capacity */
|
||||
u_int32_t lcap; /* Low capacity */
|
||||
u_int32_t gra1; /* Granulity 1(Warn to Low) */
|
||||
u_int32_t gra2; /* Granulity 2(Full to Warn) */
|
||||
char model[ACPI_CMBAT_MAXSTRLEN]; /* model identifier */
|
||||
char serial[ACPI_CMBAT_MAXSTRLEN]; /* Serial number */
|
||||
char type[ACPI_CMBAT_MAXSTRLEN]; /* Type */
|
||||
char oeminfo[ACPI_CMBAT_MAXSTRLEN]; /* OEM infomation */
|
||||
u_int32_t unit; /* 0 for mWh, 1 for mAh */
|
||||
u_int32_t dcap; /* Design Capacity */
|
||||
u_int32_t lfcap; /* Last Full capacity */
|
||||
u_int32_t btech; /* Battery Technorogy */
|
||||
u_int32_t dvol; /* Design voltage (mV) */
|
||||
u_int32_t wcap; /* WARN capacity */
|
||||
u_int32_t lcap; /* Low capacity */
|
||||
u_int32_t gra1; /* Granulity 1(Warn to Low) */
|
||||
u_int32_t gra2; /* Granulity 2(Full to Warn) */
|
||||
char model[ACPI_CMBAT_MAXSTRLEN]; /* model identifier */
|
||||
char serial[ACPI_CMBAT_MAXSTRLEN]; /* Serial number */
|
||||
char type[ACPI_CMBAT_MAXSTRLEN]; /* Type */
|
||||
char oeminfo[ACPI_CMBAT_MAXSTRLEN]; /* OEM infomation */
|
||||
};
|
||||
|
||||
struct acpi_bst {
|
||||
u_int32_t state; /* Battery State */
|
||||
u_int32_t rate; /* Present Rate */
|
||||
u_int32_t cap; /* Remaining Capacity */
|
||||
u_int32_t volt; /* Present Voltage */
|
||||
u_int32_t state; /* Battery State */
|
||||
u_int32_t rate; /* Present Rate */
|
||||
u_int32_t cap; /* Remaining Capacity */
|
||||
u_int32_t volt; /* Present Voltage */
|
||||
};
|
||||
|
||||
#define ACPI_BATT_STAT_DISCHARG 0x0001
|
||||
@ -79,28 +79,29 @@ struct acpi_bst {
|
||||
#define ACPI_BATT_STAT_MAX 0x0007
|
||||
|
||||
union acpi_battery_ioctl_arg {
|
||||
int unit; /* argument: logical unit (-1 = overall) */
|
||||
int unit; /* argument: logical unit (-1 = overall) */
|
||||
|
||||
struct acpi_battdesc battdesc;
|
||||
struct acpi_battinfo battinfo;
|
||||
struct acpi_battdesc battdesc;
|
||||
struct acpi_battinfo battinfo;
|
||||
|
||||
struct acpi_bif bif; /* for acpi_cmbat */
|
||||
struct acpi_bst bst; /* for acpi_cmbat */
|
||||
struct acpi_bif bif; /* for acpi_cmbat */
|
||||
struct acpi_bst bst; /* for acpi_cmbat */
|
||||
};
|
||||
|
||||
/* Common battery ioctl */
|
||||
#define ACPIIO_BATT_GET_UNITS _IOR('B', 0x01, int)
|
||||
#define ACPIIO_BATT_GET_TYPE _IOR('B', 0x02, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_BATT_GET_UNITS _IOR('B', 0x01, int)
|
||||
#define ACPIIO_BATT_GET_TYPE _IOR('B', 0x02, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_BATT_GET_BATTINFO _IOWR('B', 0x03, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_BATT_GET_BATTDESC _IOWR('B', 0x04, union acpi_battery_ioctl_arg)
|
||||
|
||||
/* Cotrol Method battery ioctl */
|
||||
#define ACPIIO_CMBAT_GET_BIF _IOWR('B', 0x10, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_CMBAT_GET_BST _IOWR('B', 0x11, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_CMBAT_GET_BIF _IOWR('B', 0x10, union acpi_battery_ioctl_arg)
|
||||
#define ACPIIO_CMBAT_GET_BST _IOWR('B', 0x11, union acpi_battery_ioctl_arg)
|
||||
|
||||
#define ACPIIO_ACAD_GET_STATUS _IOR('A', 1, int)
|
||||
#define ACPIIO_ACAD_GET_STATUS _IOR('A', 1, int)
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern int acpi_register_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg), void *arg);
|
||||
extern void acpi_deregister_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg));
|
||||
typedef int (*acpi_ioctl_fn)(u_long cmd, caddr_t addr, void *arg);
|
||||
extern int acpi_register_ioctl(u_long cmd, acpi_ioctl_fn fn, void *arg);
|
||||
extern void acpi_deregister_ioctl(u_long cmd, acpi_ioctl_fn fn);
|
||||
#endif
|
||||
|
@ -142,81 +142,13 @@ struct acpi_device {
|
||||
#define ACPI_IVAR_MAGIC 0x101
|
||||
#define ACPI_IVAR_PRIVATE 0x102
|
||||
|
||||
static __inline ACPI_HANDLE
|
||||
acpi_get_handle(device_t dev)
|
||||
{
|
||||
uintptr_t up;
|
||||
ACPI_HANDLE h;
|
||||
|
||||
if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_HANDLE, &up))
|
||||
return(NULL);
|
||||
h = (ACPI_HANDLE)up;
|
||||
return(h);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
acpi_set_handle(device_t dev, ACPI_HANDLE h)
|
||||
{
|
||||
uintptr_t up;
|
||||
|
||||
up = (uintptr_t)h;
|
||||
return(BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_HANDLE, up));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
acpi_get_magic(device_t dev)
|
||||
{
|
||||
uintptr_t up;
|
||||
int m;
|
||||
|
||||
if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_MAGIC, &up))
|
||||
return(0);
|
||||
m = (int)up;
|
||||
return(m);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
acpi_set_magic(device_t dev, int m)
|
||||
{
|
||||
uintptr_t up;
|
||||
|
||||
up = (uintptr_t)m;
|
||||
return(BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_MAGIC, up));
|
||||
}
|
||||
|
||||
static __inline void *
|
||||
acpi_get_private(device_t dev)
|
||||
{
|
||||
uintptr_t up;
|
||||
void *p;
|
||||
|
||||
if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_PRIVATE, &up))
|
||||
return(NULL);
|
||||
p = (void *)up;
|
||||
return(p);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
acpi_set_private(device_t dev, void *p)
|
||||
{
|
||||
uintptr_t up;
|
||||
|
||||
up = (uintptr_t)p;
|
||||
return(BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_PRIVATE, up));
|
||||
}
|
||||
|
||||
static __inline ACPI_OBJECT_TYPE
|
||||
acpi_get_type(device_t dev)
|
||||
{
|
||||
ACPI_HANDLE h;
|
||||
ACPI_OBJECT_TYPE t;
|
||||
|
||||
if ((h = acpi_get_handle(dev)) == NULL)
|
||||
return(ACPI_TYPE_NOT_FOUND);
|
||||
if (AcpiGetType(h, &t) != AE_OK)
|
||||
return(ACPI_TYPE_NOT_FOUND);
|
||||
return(t);
|
||||
}
|
||||
extern ACPI_HANDLE acpi_get_handle(device_t dev);
|
||||
extern int acpi_set_handle(device_t dev, ACPI_HANDLE h);
|
||||
extern int acpi_get_magic(device_t dev);
|
||||
extern int acpi_set_magic(device_t dev, int m);
|
||||
extern void * acpi_get_private(device_t dev);
|
||||
extern int acpi_set_private(device_t dev, void *p);
|
||||
extern ACPI_OBJECT_TYPE acpi_get_type(device_t dev);
|
||||
|
||||
#ifdef ACPI_DEBUGGER
|
||||
extern void acpi_EnterDebugger(void);
|
||||
@ -229,58 +161,67 @@ extern void acpi_EnterDebugger(void);
|
||||
#define STEP(x)
|
||||
#endif
|
||||
|
||||
#define ACPI_VPRINT(dev, acpi_sc, x...) do { \
|
||||
if (acpi_get_verbose(acpi_sc)) \
|
||||
device_printf(dev, x); \
|
||||
#define ACPI_VPRINT(dev, acpi_sc, x...) do { \
|
||||
if (acpi_get_verbose(acpi_sc)) \
|
||||
device_printf(dev, x); \
|
||||
} while (0)
|
||||
|
||||
#define ACPI_DEVINFO_PRESENT(x) (((x) & 0x9) == 9)
|
||||
extern BOOLEAN acpi_DeviceIsPresent(device_t dev);
|
||||
extern BOOLEAN acpi_BatteryIsPresent(device_t dev);
|
||||
extern BOOLEAN acpi_MatchHid(device_t dev, char *hid);
|
||||
extern ACPI_STATUS acpi_GetHandleInScope(ACPI_HANDLE parent, char *path, ACPI_HANDLE *result);
|
||||
extern ACPI_STATUS acpi_GetHandleInScope(ACPI_HANDLE parent, char *path,
|
||||
ACPI_HANDLE *result);
|
||||
extern ACPI_BUFFER *acpi_AllocBuffer(int size);
|
||||
extern ACPI_STATUS acpi_EvaluateInteger(ACPI_HANDLE handle, char *path, int *number);
|
||||
extern ACPI_STATUS acpi_ConvertBufferToInteger(ACPI_BUFFER *bufp, int *number);
|
||||
extern ACPI_STATUS acpi_EvaluateInteger(ACPI_HANDLE handle, char *path,
|
||||
int *number);
|
||||
extern ACPI_STATUS acpi_ConvertBufferToInteger(ACPI_BUFFER *bufp,
|
||||
int *number);
|
||||
extern ACPI_STATUS acpi_ForeachPackageObject(ACPI_OBJECT *obj,
|
||||
void (* func)(ACPI_OBJECT *comp, void *arg),
|
||||
void *arg);
|
||||
extern ACPI_STATUS acpi_FindIndexedResource(ACPI_BUFFER *buf, int index, ACPI_RESOURCE **resp);
|
||||
extern ACPI_STATUS acpi_AppendBufferResource(ACPI_BUFFER *buf, ACPI_RESOURCE *res);
|
||||
void (*func)(ACPI_OBJECT *comp, void *arg),
|
||||
void *arg);
|
||||
extern ACPI_STATUS acpi_FindIndexedResource(ACPI_BUFFER *buf, int index,
|
||||
ACPI_RESOURCE **resp);
|
||||
extern ACPI_STATUS acpi_AppendBufferResource(ACPI_BUFFER *buf,
|
||||
ACPI_RESOURCE *res);
|
||||
extern ACPI_STATUS acpi_SetIntrModel(int model);
|
||||
|
||||
extern ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
|
||||
extern ACPI_STATUS acpi_Enable(struct acpi_softc *sc);
|
||||
extern ACPI_STATUS acpi_Disable(struct acpi_softc *sc);
|
||||
|
||||
struct acpi_parse_resource_set {
|
||||
void (* set_init)(device_t dev, void **context);
|
||||
void (* set_done)(device_t dev, void *context);
|
||||
void (* set_ioport)(device_t dev, void *context, u_int32_t base, u_int32_t length);
|
||||
void (* set_iorange)(device_t dev, void *context, u_int32_t low, u_int32_t high,
|
||||
u_int32_t length, u_int32_t align);
|
||||
void (* set_memory)(device_t dev, void *context, u_int32_t base, u_int32_t length);
|
||||
void (* set_memoryrange)(device_t dev, void *context, u_int32_t low, u_int32_t high,
|
||||
u_int32_t length, u_int32_t align);
|
||||
void (* set_irq)(device_t dev, void *context, u_int32_t *irq, int cout);
|
||||
void (* set_drq)(device_t dev, void *context, u_int32_t *drq, int count);
|
||||
void (* set_start_dependant)(device_t dev, void *context, int preference);
|
||||
void (* set_end_dependant)(device_t dev, void *context);
|
||||
void (*set_init)(device_t dev, void **context);
|
||||
void (*set_done)(device_t dev, void *context);
|
||||
void (*set_ioport)(device_t dev, void *context, u_int32_t base,
|
||||
u_int32_t length);
|
||||
void (*set_iorange)(device_t dev, void *context,
|
||||
u_int32_t low, u_int32_t high,
|
||||
u_int32_t length, u_int32_t align);
|
||||
void (*set_memory)(device_t dev, void *context, u_int32_t base,
|
||||
u_int32_t length);
|
||||
void (*set_memoryrange)(device_t dev, void *context, u_int32_t low,
|
||||
u_int32_t high, u_int32_t length,
|
||||
u_int32_t align);
|
||||
void (*set_irq)(device_t dev, void *context, u_int32_t *irq,
|
||||
int cout);
|
||||
void (*set_drq)(device_t dev, void *context, u_int32_t *drq,
|
||||
int count);
|
||||
void (*set_start_dependant)(device_t dev, void *context,
|
||||
int preference);
|
||||
void (*set_end_dependant)(device_t dev, void *context);
|
||||
};
|
||||
|
||||
extern struct acpi_parse_resource_set acpi_res_parse_set;
|
||||
extern ACPI_STATUS acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
|
||||
struct acpi_parse_resource_set *set);
|
||||
struct acpi_parse_resource_set *set);
|
||||
/* XXX until Intel fix this in their headers, based on NEXT_RESOURCE */
|
||||
#define ACPI_RESOURCE_NEXT(Res) (ACPI_RESOURCE *)((UINT8 *) Res + Res->Length)
|
||||
#define ACPI_RESOURCE_NEXT(Res) (ACPI_RESOURCE *)((UINT8 *)Res + Res->Length)
|
||||
|
||||
/*
|
||||
* ACPI event handling
|
||||
*/
|
||||
extern UINT32 acpi_eventhandler_power_button_for_sleep(void *context);
|
||||
extern UINT32 acpi_eventhandler_power_button_for_wakeup(void *context);
|
||||
extern UINT32 acpi_eventhandler_sleep_button_for_sleep(void *context);
|
||||
extern UINT32 acpi_eventhandler_sleep_button_for_wakeup(void *context);
|
||||
/* ACPI event handling */
|
||||
extern UINT32 acpi_eventhandler_power_button_for_sleep(void *context);
|
||||
extern UINT32 acpi_eventhandler_power_button_for_wakeup(void *context);
|
||||
extern UINT32 acpi_eventhandler_sleep_button_for_sleep(void *context);
|
||||
extern UINT32 acpi_eventhandler_sleep_button_for_wakeup(void *context);
|
||||
|
||||
#define ACPI_EVENT_PRI_FIRST 0
|
||||
#define ACPI_EVENT_PRI_DEFAULT 10000
|
||||
@ -291,48 +232,40 @@ typedef void (*acpi_event_handler_t)(void *, int);
|
||||
EVENTHANDLER_DECLARE(acpi_sleep_event, acpi_event_handler_t);
|
||||
EVENTHANDLER_DECLARE(acpi_wakeup_event, acpi_event_handler_t);
|
||||
|
||||
/*
|
||||
* Device power control.
|
||||
*/
|
||||
extern ACPI_STATUS acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state);
|
||||
/* Device power control. */
|
||||
extern ACPI_STATUS acpi_pwr_switch_consumer(ACPI_HANDLE consumer,
|
||||
int state);
|
||||
|
||||
/*
|
||||
* Misc.
|
||||
*/
|
||||
/* Misc. */
|
||||
static __inline struct acpi_softc *
|
||||
acpi_device_get_parent_softc(device_t child)
|
||||
{
|
||||
device_t parent;
|
||||
|
||||
parent = device_get_parent(child);
|
||||
if (parent == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
return(device_get_softc(parent));
|
||||
if (parent == NULL)
|
||||
return (NULL);
|
||||
return (device_get_softc(parent));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
acpi_get_verbose(struct acpi_softc *sc)
|
||||
{
|
||||
if (sc)
|
||||
return(sc->acpi_verbose);
|
||||
return(0);
|
||||
return (sc->acpi_verbose);
|
||||
return (0);
|
||||
}
|
||||
|
||||
extern char *acpi_name(ACPI_HANDLE handle);
|
||||
extern int acpi_avoid(ACPI_HANDLE handle);
|
||||
extern int acpi_disabled(char *subsys);
|
||||
|
||||
extern void acpi_device_enable_wake_capability(ACPI_HANDLE h, int enable);
|
||||
extern void acpi_device_enable_wake_event(ACPI_HANDLE h);
|
||||
|
||||
extern int acpi_machdep_init(device_t dev);
|
||||
extern void acpi_install_wakeup_handler(struct acpi_softc *sc);
|
||||
extern int acpi_sleep_machdep(struct acpi_softc *sc, int state);
|
||||
|
||||
/*
|
||||
* Battery Abstraction.
|
||||
*/
|
||||
/* Battery Abstraction. */
|
||||
struct acpi_battinfo;
|
||||
struct acpi_battdesc;
|
||||
|
||||
@ -344,15 +277,10 @@ extern int acpi_battery_get_battdesc(int, struct acpi_battdesc *);
|
||||
|
||||
extern int acpi_cmbat_get_battinfo(int, struct acpi_battinfo *);
|
||||
|
||||
/*
|
||||
* Embedded controller.
|
||||
*/
|
||||
/* Embedded controller. */
|
||||
extern void acpi_ec_ecdt_probe(device_t);
|
||||
|
||||
/*
|
||||
* AC adapter interface.
|
||||
*/
|
||||
|
||||
/* AC adapter interface. */
|
||||
extern int acpi_acad_get_acline(int *);
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
@ -365,9 +293,6 @@ extern int acpi_acad_get_acline(int *);
|
||||
#endif
|
||||
|
||||
#ifdef ACPI_USE_THREADS
|
||||
/*
|
||||
* ACPI task kernel thread initialization.
|
||||
*/
|
||||
/* ACPI task kernel thread initialization. */
|
||||
extern int acpi_task_thread_init(void);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user