summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/acpica/acpi_cpu.c')
-rw-r--r--sys/dev/acpica/acpi_cpu.c210
1 files changed, 111 insertions, 99 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index dc096ba..f6c5a59 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -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);
-
- 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)"));
+ 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)"));
}
}
- 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)
+ }
+ 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);
+ /* 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 */
+ /*
+ * 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);
}
OpenPOWER on IntegriCloud