Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: cpuidle: Single/Global registration of idle states cpuidle: Split cpuidle_state structure and move per-cpu statistics fields cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev->prepare() cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state ACPI: Fix CONFIG_ACPI_DOCK=n compiler warning ACPI: Export FADT pm_profile integer value to userspace thermal: Prevent polling from happening during system suspend ACPI: Drop ACPI_NO_HARDWARE_INIT ACPI atomicio: Convert width in bits to bytes in __acpi_ioremap_fast() PNPACPI: Simplify disabled resource registration ACPI: Fix possible recursive locking in hwregs.c ACPI: use kstrdup() mrst pmu: update comment tools/power turbostat: less verbose debugging
This commit is contained in:
@@ -62,8 +62,9 @@ static int __cpuidle_register_device(struct cpuidle_device *dev);
|
||||
int cpuidle_idle_call(void)
|
||||
{
|
||||
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
|
||||
struct cpuidle_driver *drv = cpuidle_get_driver();
|
||||
struct cpuidle_state *target_state;
|
||||
int next_state;
|
||||
int next_state, entered_state;
|
||||
|
||||
if (off)
|
||||
return -ENODEV;
|
||||
@@ -84,45 +85,36 @@ int cpuidle_idle_call(void)
|
||||
hrtimer_peek_ahead_timers();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call the device's prepare function before calling the
|
||||
* governor's select function. ->prepare gives the device's
|
||||
* cpuidle driver a chance to update any dynamic information
|
||||
* of its cpuidle states for the current idle period, e.g.
|
||||
* state availability, latencies, residencies, etc.
|
||||
*/
|
||||
if (dev->prepare)
|
||||
dev->prepare(dev);
|
||||
|
||||
/* ask the governor for the next state */
|
||||
next_state = cpuidle_curr_governor->select(dev);
|
||||
next_state = cpuidle_curr_governor->select(drv, dev);
|
||||
if (need_resched()) {
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
target_state = &dev->states[next_state];
|
||||
|
||||
/* enter the state and update stats */
|
||||
dev->last_state = target_state;
|
||||
target_state = &drv->states[next_state];
|
||||
|
||||
trace_power_start(POWER_CSTATE, next_state, dev->cpu);
|
||||
trace_cpu_idle(next_state, dev->cpu);
|
||||
|
||||
dev->last_residency = target_state->enter(dev, target_state);
|
||||
entered_state = target_state->enter(dev, drv, next_state);
|
||||
|
||||
trace_power_end(dev->cpu);
|
||||
trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
|
||||
|
||||
if (dev->last_state)
|
||||
target_state = dev->last_state;
|
||||
|
||||
target_state->time += (unsigned long long)dev->last_residency;
|
||||
target_state->usage++;
|
||||
if (entered_state >= 0) {
|
||||
/* Update cpuidle counters */
|
||||
/* This can be moved to within driver enter routine
|
||||
* but that results in multiple copies of same code.
|
||||
*/
|
||||
dev->states_usage[entered_state].time +=
|
||||
(unsigned long long)dev->last_residency;
|
||||
dev->states_usage[entered_state].usage++;
|
||||
}
|
||||
|
||||
/* give the governor an opportunity to reflect on the outcome */
|
||||
if (cpuidle_curr_governor->reflect)
|
||||
cpuidle_curr_governor->reflect(dev);
|
||||
cpuidle_curr_governor->reflect(dev, entered_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -173,11 +165,11 @@ void cpuidle_resume_and_unlock(void)
|
||||
EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_CPU_RELAX
|
||||
static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
|
||||
static int poll_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
ktime_t t1, t2;
|
||||
s64 diff;
|
||||
int ret;
|
||||
|
||||
t1 = ktime_get();
|
||||
local_irq_enable();
|
||||
@@ -189,15 +181,14 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
|
||||
if (diff > INT_MAX)
|
||||
diff = INT_MAX;
|
||||
|
||||
ret = (int) diff;
|
||||
return ret;
|
||||
dev->last_residency = (int) diff;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void poll_idle_init(struct cpuidle_device *dev)
|
||||
static void poll_idle_init(struct cpuidle_driver *drv)
|
||||
{
|
||||
struct cpuidle_state *state = &dev->states[0];
|
||||
|
||||
cpuidle_set_statedata(state, NULL);
|
||||
struct cpuidle_state *state = &drv->states[0];
|
||||
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
|
||||
snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
|
||||
@@ -208,7 +199,7 @@ static void poll_idle_init(struct cpuidle_device *dev)
|
||||
state->enter = poll_idle;
|
||||
}
|
||||
#else
|
||||
static void poll_idle_init(struct cpuidle_device *dev) {}
|
||||
static void poll_idle_init(struct cpuidle_driver *drv) {}
|
||||
#endif /* CONFIG_ARCH_HAS_CPU_RELAX */
|
||||
|
||||
/**
|
||||
@@ -235,21 +226,20 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
poll_idle_init(dev);
|
||||
poll_idle_init(cpuidle_get_driver());
|
||||
|
||||
if ((ret = cpuidle_add_state_sysfs(dev)))
|
||||
return ret;
|
||||
|
||||
if (cpuidle_curr_governor->enable &&
|
||||
(ret = cpuidle_curr_governor->enable(dev)))
|
||||
(ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev)))
|
||||
goto fail_sysfs;
|
||||
|
||||
for (i = 0; i < dev->state_count; i++) {
|
||||
dev->states[i].usage = 0;
|
||||
dev->states[i].time = 0;
|
||||
dev->states_usage[i].usage = 0;
|
||||
dev->states_usage[i].time = 0;
|
||||
}
|
||||
dev->last_residency = 0;
|
||||
dev->last_state = NULL;
|
||||
|
||||
smp_wmb();
|
||||
|
||||
@@ -283,7 +273,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev)
|
||||
dev->enabled = 0;
|
||||
|
||||
if (cpuidle_curr_governor->disable)
|
||||
cpuidle_curr_governor->disable(dev);
|
||||
cpuidle_curr_governor->disable(cpuidle_get_driver(), dev);
|
||||
|
||||
cpuidle_remove_state_sysfs(dev);
|
||||
enabled_devices--;
|
||||
@@ -311,26 +301,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
|
||||
|
||||
init_completion(&dev->kobj_unregister);
|
||||
|
||||
/*
|
||||
* cpuidle driver should set the dev->power_specified bit
|
||||
* before registering the device if the driver provides
|
||||
* power_usage numbers.
|
||||
*
|
||||
* For those devices whose ->power_specified is not set,
|
||||
* we fill in power_usage with decreasing values as the
|
||||
* cpuidle code has an implicit assumption that state Cn
|
||||
* uses less power than C(n-1).
|
||||
*
|
||||
* With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
|
||||
* an power value of -1. So we use -2, -3, etc, for other
|
||||
* c-states.
|
||||
*/
|
||||
if (!dev->power_specified) {
|
||||
int i;
|
||||
for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++)
|
||||
dev->states[i].power_usage = -1 - i;
|
||||
}
|
||||
|
||||
per_cpu(cpuidle_devices, dev->cpu) = dev;
|
||||
list_add(&dev->device_list, &cpuidle_detected_devices);
|
||||
if ((ret = cpuidle_add_sysfs(sys_dev))) {
|
||||
|
Reference in New Issue
Block a user