Merge branch 'pm-cpuidle'
This commit is contained in:
Коммит
3db0bc9767
|
@ -427,18 +427,11 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
|
||||||
* Initialize missing things
|
* Initialize missing things
|
||||||
*/
|
*/
|
||||||
if (pr->flags.need_hotplug_init) {
|
if (pr->flags.need_hotplug_init) {
|
||||||
struct cpuidle_driver *idle_driver =
|
|
||||||
cpuidle_get_driver();
|
|
||||||
|
|
||||||
printk(KERN_INFO "Will online and init hotplugged "
|
printk(KERN_INFO "Will online and init hotplugged "
|
||||||
"CPU: %d\n", pr->id);
|
"CPU: %d\n", pr->id);
|
||||||
WARN(acpi_processor_start(pr), "Failed to start CPU:"
|
WARN(acpi_processor_start(pr), "Failed to start CPU:"
|
||||||
" %d\n", pr->id);
|
" %d\n", pr->id);
|
||||||
pr->flags.need_hotplug_init = 0;
|
pr->flags.need_hotplug_init = 0;
|
||||||
if (idle_driver && !strcmp(idle_driver->name,
|
|
||||||
"intel_idle")) {
|
|
||||||
intel_idle_cpu_init(pr->id);
|
|
||||||
}
|
|
||||||
/* Normal CPU soft online event */
|
/* Normal CPU soft online event */
|
||||||
} else {
|
} else {
|
||||||
acpi_processor_ppc_has_changed(pr, 0);
|
acpi_processor_ppc_has_changed(pr, 0);
|
||||||
|
|
|
@ -221,10 +221,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Suspend / resume control
|
|
||||||
*/
|
|
||||||
static int acpi_idle_suspend;
|
|
||||||
static u32 saved_bm_rld;
|
static u32 saved_bm_rld;
|
||||||
|
|
||||||
static void acpi_idle_bm_rld_save(void)
|
static void acpi_idle_bm_rld_save(void)
|
||||||
|
@ -243,21 +239,13 @@ static void acpi_idle_bm_rld_restore(void)
|
||||||
|
|
||||||
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
|
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
|
||||||
{
|
{
|
||||||
if (acpi_idle_suspend == 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
acpi_idle_bm_rld_save();
|
acpi_idle_bm_rld_save();
|
||||||
acpi_idle_suspend = 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int acpi_processor_resume(struct acpi_device * device)
|
int acpi_processor_resume(struct acpi_device * device)
|
||||||
{
|
{
|
||||||
if (acpi_idle_suspend == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
acpi_idle_bm_rld_restore();
|
acpi_idle_bm_rld_restore();
|
||||||
acpi_idle_suspend = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +583,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
||||||
*/
|
*/
|
||||||
cx->valid = 1;
|
cx->valid = 1;
|
||||||
|
|
||||||
cx->latency_ticks = cx->latency;
|
|
||||||
/*
|
/*
|
||||||
* On older chipsets, BM_RLD needs to be set
|
* On older chipsets, BM_RLD needs to be set
|
||||||
* in order for Bus Master activity to wake the
|
* in order for Bus Master activity to wake the
|
||||||
|
@ -628,7 +615,6 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
|
||||||
if (!cx->address)
|
if (!cx->address)
|
||||||
break;
|
break;
|
||||||
cx->valid = 1;
|
cx->valid = 1;
|
||||||
cx->latency_ticks = cx->latency; /* Normalize latency */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_STATE_C3:
|
case ACPI_STATE_C3:
|
||||||
|
@ -763,11 +749,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
if (acpi_idle_suspend) {
|
|
||||||
local_irq_enable();
|
|
||||||
cpu_relax();
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
lapic_timer_state_broadcast(pr, cx, 1);
|
lapic_timer_state_broadcast(pr, cx, 1);
|
||||||
kt1 = ktime_get_real();
|
kt1 = ktime_get_real();
|
||||||
|
@ -779,7 +760,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
|
||||||
dev->last_residency = (int)idle_time;
|
dev->last_residency = (int)idle_time;
|
||||||
|
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
cx->usage++;
|
|
||||||
lapic_timer_state_broadcast(pr, cx, 0);
|
lapic_timer_state_broadcast(pr, cx, 0);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
@ -838,11 +818,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
if (acpi_idle_suspend) {
|
|
||||||
local_irq_enable();
|
|
||||||
cpu_relax();
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
||||||
current_thread_info()->status &= ~TS_POLLING;
|
current_thread_info()->status &= ~TS_POLLING;
|
||||||
|
@ -887,10 +862,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||||
if (cx->entry_method != ACPI_CSTATE_FFH)
|
if (cx->entry_method != ACPI_CSTATE_FFH)
|
||||||
current_thread_info()->status |= TS_POLLING;
|
current_thread_info()->status |= TS_POLLING;
|
||||||
|
|
||||||
cx->usage++;
|
|
||||||
|
|
||||||
lapic_timer_state_broadcast(pr, cx, 0);
|
lapic_timer_state_broadcast(pr, cx, 0);
|
||||||
cx->time += idle_time;
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,8 +900,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||||
drv, drv->safe_state_index);
|
drv, drv->safe_state_index);
|
||||||
} else {
|
} else {
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
if (!acpi_idle_suspend)
|
acpi_safe_halt();
|
||||||
acpi_safe_halt();
|
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
@ -937,11 +908,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
if (acpi_idle_suspend) {
|
|
||||||
local_irq_enable();
|
|
||||||
cpu_relax();
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
||||||
current_thread_info()->status &= ~TS_POLLING;
|
current_thread_info()->status &= ~TS_POLLING;
|
||||||
|
@ -1014,10 +980,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||||
if (cx->entry_method != ACPI_CSTATE_FFH)
|
if (cx->entry_method != ACPI_CSTATE_FFH)
|
||||||
current_thread_info()->status |= TS_POLLING;
|
current_thread_info()->status |= TS_POLLING;
|
||||||
|
|
||||||
cx->usage++;
|
|
||||||
|
|
||||||
lapic_timer_state_broadcast(pr, cx, 0);
|
lapic_timer_state_broadcast(pr, cx, 0);
|
||||||
cx->time += idle_time;
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/async.h>
|
#include <linux/async.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
|
#include <linux/cpuidle.h>
|
||||||
#include "../base.h"
|
#include "../base.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
|
||||||
|
@ -467,6 +467,7 @@ static void dpm_resume_noirq(pm_message_t state)
|
||||||
mutex_unlock(&dpm_list_mtx);
|
mutex_unlock(&dpm_list_mtx);
|
||||||
dpm_show_time(starttime, state, "noirq");
|
dpm_show_time(starttime, state, "noirq");
|
||||||
resume_device_irqs();
|
resume_device_irqs();
|
||||||
|
cpuidle_resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -867,6 +868,7 @@ static int dpm_suspend_noirq(pm_message_t state)
|
||||||
ktime_t starttime = ktime_get();
|
ktime_t starttime = ktime_get();
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
cpuidle_pause();
|
||||||
suspend_device_irqs();
|
suspend_device_irqs();
|
||||||
mutex_lock(&dpm_list_mtx);
|
mutex_lock(&dpm_list_mtx);
|
||||||
while (!list_empty(&dpm_late_early_list)) {
|
while (!list_empty(&dpm_late_early_list)) {
|
||||||
|
|
|
@ -201,6 +201,22 @@ void cpuidle_resume_and_unlock(void)
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
|
EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
|
||||||
|
|
||||||
|
/* Currently used in suspend/resume path to suspend cpuidle */
|
||||||
|
void cpuidle_pause(void)
|
||||||
|
{
|
||||||
|
mutex_lock(&cpuidle_lock);
|
||||||
|
cpuidle_uninstall_idle_handler();
|
||||||
|
mutex_unlock(&cpuidle_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Currently used in suspend/resume path to resume cpuidle */
|
||||||
|
void cpuidle_resume(void)
|
||||||
|
{
|
||||||
|
mutex_lock(&cpuidle_lock);
|
||||||
|
cpuidle_install_idle_handler();
|
||||||
|
mutex_unlock(&cpuidle_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpuidle_wrap_enter - performs timekeeping and irqen around enter function
|
* cpuidle_wrap_enter - performs timekeeping and irqen around enter function
|
||||||
* @dev: pointer to a valid cpuidle_device object
|
* @dev: pointer to a valid cpuidle_device object
|
||||||
|
@ -265,7 +281,6 @@ static void poll_idle_init(struct cpuidle_driver *drv)
|
||||||
state->power_usage = -1;
|
state->power_usage = -1;
|
||||||
state->flags = 0;
|
state->flags = 0;
|
||||||
state->enter = poll_idle;
|
state->enter = poll_idle;
|
||||||
state->disable = 0;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void poll_idle_init(struct cpuidle_driver *drv) {}
|
static void poll_idle_init(struct cpuidle_driver *drv) {}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
static struct cpuidle_driver *cpuidle_curr_driver;
|
static struct cpuidle_driver *cpuidle_curr_driver;
|
||||||
DEFINE_SPINLOCK(cpuidle_driver_lock);
|
DEFINE_SPINLOCK(cpuidle_driver_lock);
|
||||||
|
int cpuidle_driver_refcount;
|
||||||
|
|
||||||
static void __cpuidle_register_driver(struct cpuidle_driver *drv)
|
static void __cpuidle_register_driver(struct cpuidle_driver *drv)
|
||||||
{
|
{
|
||||||
|
@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv)
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&cpuidle_driver_lock);
|
spin_lock(&cpuidle_driver_lock);
|
||||||
cpuidle_curr_driver = NULL;
|
|
||||||
|
if (!WARN_ON(cpuidle_driver_refcount > 0))
|
||||||
|
cpuidle_curr_driver = NULL;
|
||||||
|
|
||||||
spin_unlock(&cpuidle_driver_lock);
|
spin_unlock(&cpuidle_driver_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
|
EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
|
||||||
|
|
||||||
|
struct cpuidle_driver *cpuidle_driver_ref(void)
|
||||||
|
{
|
||||||
|
struct cpuidle_driver *drv;
|
||||||
|
|
||||||
|
spin_lock(&cpuidle_driver_lock);
|
||||||
|
|
||||||
|
drv = cpuidle_curr_driver;
|
||||||
|
cpuidle_driver_refcount++;
|
||||||
|
|
||||||
|
spin_unlock(&cpuidle_driver_lock);
|
||||||
|
return drv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpuidle_driver_unref(void)
|
||||||
|
{
|
||||||
|
spin_lock(&cpuidle_driver_lock);
|
||||||
|
|
||||||
|
if (!WARN_ON(cpuidle_driver_refcount <= 0))
|
||||||
|
cpuidle_driver_refcount--;
|
||||||
|
|
||||||
|
spin_unlock(&cpuidle_driver_lock);
|
||||||
|
}
|
||||||
|
|
|
@ -281,7 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
|
||||||
* unless the timer is happening really really soon.
|
* unless the timer is happening really really soon.
|
||||||
*/
|
*/
|
||||||
if (data->expected_us > 5 &&
|
if (data->expected_us > 5 &&
|
||||||
drv->states[CPUIDLE_DRIVER_STATE_START].disable == 0)
|
dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0)
|
||||||
data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
|
data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -290,8 +290,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
|
||||||
*/
|
*/
|
||||||
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
|
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
|
||||||
struct cpuidle_state *s = &drv->states[i];
|
struct cpuidle_state *s = &drv->states[i];
|
||||||
|
struct cpuidle_state_usage *su = &dev->states_usage[i];
|
||||||
|
|
||||||
if (s->disable)
|
if (su->disable)
|
||||||
continue;
|
continue;
|
||||||
if (s->target_residency > data->predicted_us)
|
if (s->target_residency > data->predicted_us)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -217,7 +217,8 @@ struct cpuidle_state_attr {
|
||||||
struct attribute attr;
|
struct attribute attr;
|
||||||
ssize_t (*show)(struct cpuidle_state *, \
|
ssize_t (*show)(struct cpuidle_state *, \
|
||||||
struct cpuidle_state_usage *, char *);
|
struct cpuidle_state_usage *, char *);
|
||||||
ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
|
ssize_t (*store)(struct cpuidle_state *, \
|
||||||
|
struct cpuidle_state_usage *, const char *, size_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define define_one_state_ro(_name, show) \
|
#define define_one_state_ro(_name, show) \
|
||||||
|
@ -233,21 +234,22 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
|
||||||
return sprintf(buf, "%u\n", state->_name);\
|
return sprintf(buf, "%u\n", state->_name);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define define_store_state_function(_name) \
|
#define define_store_state_ull_function(_name) \
|
||||||
static ssize_t store_state_##_name(struct cpuidle_state *state, \
|
static ssize_t store_state_##_name(struct cpuidle_state *state, \
|
||||||
|
struct cpuidle_state_usage *state_usage, \
|
||||||
const char *buf, size_t size) \
|
const char *buf, size_t size) \
|
||||||
{ \
|
{ \
|
||||||
long value; \
|
unsigned long long value; \
|
||||||
int err; \
|
int err; \
|
||||||
if (!capable(CAP_SYS_ADMIN)) \
|
if (!capable(CAP_SYS_ADMIN)) \
|
||||||
return -EPERM; \
|
return -EPERM; \
|
||||||
err = kstrtol(buf, 0, &value); \
|
err = kstrtoull(buf, 0, &value); \
|
||||||
if (err) \
|
if (err) \
|
||||||
return err; \
|
return err; \
|
||||||
if (value) \
|
if (value) \
|
||||||
state->disable = 1; \
|
state_usage->_name = 1; \
|
||||||
else \
|
else \
|
||||||
state->disable = 0; \
|
state_usage->_name = 0; \
|
||||||
return size; \
|
return size; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +275,8 @@ define_show_state_ull_function(usage)
|
||||||
define_show_state_ull_function(time)
|
define_show_state_ull_function(time)
|
||||||
define_show_state_str_function(name)
|
define_show_state_str_function(name)
|
||||||
define_show_state_str_function(desc)
|
define_show_state_str_function(desc)
|
||||||
define_show_state_function(disable)
|
define_show_state_ull_function(disable)
|
||||||
define_store_state_function(disable)
|
define_store_state_ull_function(disable)
|
||||||
|
|
||||||
define_one_state_ro(name, show_state_name);
|
define_one_state_ro(name, show_state_name);
|
||||||
define_one_state_ro(desc, show_state_desc);
|
define_one_state_ro(desc, show_state_desc);
|
||||||
|
@ -318,10 +320,11 @@ static ssize_t cpuidle_state_store(struct kobject *kobj,
|
||||||
{
|
{
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
struct cpuidle_state *state = kobj_to_state(kobj);
|
struct cpuidle_state *state = kobj_to_state(kobj);
|
||||||
|
struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
|
||||||
struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
|
struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
|
||||||
|
|
||||||
if (cattr->store)
|
if (cattr->store)
|
||||||
ret = cattr->store(state, buf, size);
|
ret = cattr->store(state, state_usage, buf, size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ static const struct idle_cpu *icpu;
|
||||||
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
|
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
|
||||||
static int intel_idle(struct cpuidle_device *dev,
|
static int intel_idle(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv, int index);
|
struct cpuidle_driver *drv, int index);
|
||||||
|
static int intel_idle_cpu_init(int cpu);
|
||||||
|
|
||||||
static struct cpuidle_state *cpuidle_state_table;
|
static struct cpuidle_state *cpuidle_state_table;
|
||||||
|
|
||||||
|
@ -302,22 +303,35 @@ static void __setup_broadcast_timer(void *arg)
|
||||||
clockevents_notify(reason, &cpu);
|
clockevents_notify(reason, &cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_broadcast_cpuhp_notify(struct notifier_block *n,
|
static int cpu_hotplug_notify(struct notifier_block *n,
|
||||||
unsigned long action, void *hcpu)
|
unsigned long action, void *hcpu)
|
||||||
{
|
{
|
||||||
int hotcpu = (unsigned long)hcpu;
|
int hotcpu = (unsigned long)hcpu;
|
||||||
|
struct cpuidle_device *dev;
|
||||||
|
|
||||||
switch (action & 0xf) {
|
switch (action & 0xf) {
|
||||||
case CPU_ONLINE:
|
case CPU_ONLINE:
|
||||||
smp_call_function_single(hotcpu, __setup_broadcast_timer,
|
|
||||||
(void *)true, 1);
|
if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
|
||||||
|
smp_call_function_single(hotcpu, __setup_broadcast_timer,
|
||||||
|
(void *)true, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some systems can hotplug a cpu at runtime after
|
||||||
|
* the kernel has booted, we have to initialize the
|
||||||
|
* driver in this case
|
||||||
|
*/
|
||||||
|
dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu);
|
||||||
|
if (!dev->registered)
|
||||||
|
intel_idle_cpu_init(hotcpu);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct notifier_block setup_broadcast_notifier = {
|
static struct notifier_block cpu_hotplug_notifier = {
|
||||||
.notifier_call = setup_broadcast_cpuhp_notify,
|
.notifier_call = cpu_hotplug_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void auto_demotion_disable(void *dummy)
|
static void auto_demotion_disable(void *dummy)
|
||||||
|
@ -405,10 +419,10 @@ static int intel_idle_probe(void)
|
||||||
|
|
||||||
if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
|
if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
|
||||||
lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
|
lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
|
||||||
else {
|
else
|
||||||
on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
|
on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
|
||||||
register_cpu_notifier(&setup_broadcast_notifier);
|
|
||||||
}
|
register_cpu_notifier(&cpu_hotplug_notifier);
|
||||||
|
|
||||||
pr_debug(PREFIX "v" INTEL_IDLE_VERSION
|
pr_debug(PREFIX "v" INTEL_IDLE_VERSION
|
||||||
" model 0x%X\n", boot_cpu_data.x86_model);
|
" model 0x%X\n", boot_cpu_data.x86_model);
|
||||||
|
@ -494,7 +508,7 @@ static int intel_idle_cpuidle_driver_init(void)
|
||||||
* allocate, initialize, register cpuidle_devices
|
* allocate, initialize, register cpuidle_devices
|
||||||
* @cpu: cpu/core to initialize
|
* @cpu: cpu/core to initialize
|
||||||
*/
|
*/
|
||||||
int intel_idle_cpu_init(int cpu)
|
static int intel_idle_cpu_init(int cpu)
|
||||||
{
|
{
|
||||||
int cstate;
|
int cstate;
|
||||||
struct cpuidle_device *dev;
|
struct cpuidle_device *dev;
|
||||||
|
@ -539,7 +553,6 @@ int intel_idle_cpu_init(int cpu)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(intel_idle_cpu_init);
|
|
||||||
|
|
||||||
static int __init intel_idle_init(void)
|
static int __init intel_idle_init(void)
|
||||||
{
|
{
|
||||||
|
@ -581,10 +594,10 @@ static void __exit intel_idle_exit(void)
|
||||||
intel_idle_cpuidle_devices_uninit();
|
intel_idle_cpuidle_devices_uninit();
|
||||||
cpuidle_unregister_driver(&intel_idle_driver);
|
cpuidle_unregister_driver(&intel_idle_driver);
|
||||||
|
|
||||||
if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) {
|
|
||||||
|
if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
|
||||||
on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
|
on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
|
||||||
unregister_cpu_notifier(&setup_broadcast_notifier);
|
unregister_cpu_notifier(&cpu_hotplug_notifier);
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,7 @@ struct acpi_processor_cx {
|
||||||
u8 entry_method;
|
u8 entry_method;
|
||||||
u8 index;
|
u8 index;
|
||||||
u32 latency;
|
u32 latency;
|
||||||
u32 latency_ticks;
|
|
||||||
u32 power;
|
u32 power;
|
||||||
u32 usage;
|
|
||||||
u64 time;
|
|
||||||
u8 bm_sts_skip;
|
u8 bm_sts_skip;
|
||||||
char desc[ACPI_CX_DESC_LEN];
|
char desc[ACPI_CX_DESC_LEN];
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct cpuidle_driver;
|
||||||
struct cpuidle_state_usage {
|
struct cpuidle_state_usage {
|
||||||
void *driver_data;
|
void *driver_data;
|
||||||
|
|
||||||
|
unsigned long long disable;
|
||||||
unsigned long long usage;
|
unsigned long long usage;
|
||||||
unsigned long long time; /* in US */
|
unsigned long long time; /* in US */
|
||||||
};
|
};
|
||||||
|
@ -46,7 +47,6 @@ struct cpuidle_state {
|
||||||
unsigned int exit_latency; /* in US */
|
unsigned int exit_latency; /* in US */
|
||||||
int power_usage; /* in mW */
|
int power_usage; /* in mW */
|
||||||
unsigned int target_residency; /* in US */
|
unsigned int target_residency; /* in US */
|
||||||
unsigned int disable;
|
|
||||||
|
|
||||||
int (*enter) (struct cpuidle_device *dev,
|
int (*enter) (struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv,
|
struct cpuidle_driver *drv,
|
||||||
|
@ -136,13 +136,17 @@ struct cpuidle_driver {
|
||||||
extern void disable_cpuidle(void);
|
extern void disable_cpuidle(void);
|
||||||
extern int cpuidle_idle_call(void);
|
extern int cpuidle_idle_call(void);
|
||||||
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
|
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
|
||||||
struct cpuidle_driver *cpuidle_get_driver(void);
|
extern struct cpuidle_driver *cpuidle_get_driver(void);
|
||||||
|
extern struct cpuidle_driver *cpuidle_driver_ref(void);
|
||||||
|
extern void cpuidle_driver_unref(void);
|
||||||
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
|
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
|
||||||
extern int cpuidle_register_device(struct cpuidle_device *dev);
|
extern int cpuidle_register_device(struct cpuidle_device *dev);
|
||||||
extern void cpuidle_unregister_device(struct cpuidle_device *dev);
|
extern void cpuidle_unregister_device(struct cpuidle_device *dev);
|
||||||
|
|
||||||
extern void cpuidle_pause_and_lock(void);
|
extern void cpuidle_pause_and_lock(void);
|
||||||
extern void cpuidle_resume_and_unlock(void);
|
extern void cpuidle_resume_and_unlock(void);
|
||||||
|
extern void cpuidle_pause(void);
|
||||||
|
extern void cpuidle_resume(void);
|
||||||
extern int cpuidle_enable_device(struct cpuidle_device *dev);
|
extern int cpuidle_enable_device(struct cpuidle_device *dev);
|
||||||
extern void cpuidle_disable_device(struct cpuidle_device *dev);
|
extern void cpuidle_disable_device(struct cpuidle_device *dev);
|
||||||
extern int cpuidle_wrap_enter(struct cpuidle_device *dev,
|
extern int cpuidle_wrap_enter(struct cpuidle_device *dev,
|
||||||
|
@ -157,6 +161,8 @@ static inline int cpuidle_idle_call(void) { return -ENODEV; }
|
||||||
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
|
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
|
||||||
{return -ENODEV; }
|
{return -ENODEV; }
|
||||||
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
|
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
|
||||||
|
static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; }
|
||||||
|
static inline void cpuidle_driver_unref(void) {}
|
||||||
static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
|
static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
|
||||||
static inline int cpuidle_register_device(struct cpuidle_device *dev)
|
static inline int cpuidle_register_device(struct cpuidle_device *dev)
|
||||||
{return -ENODEV; }
|
{return -ENODEV; }
|
||||||
|
@ -164,6 +170,8 @@ static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
|
||||||
|
|
||||||
static inline void cpuidle_pause_and_lock(void) { }
|
static inline void cpuidle_pause_and_lock(void) { }
|
||||||
static inline void cpuidle_resume_and_unlock(void) { }
|
static inline void cpuidle_resume_and_unlock(void) { }
|
||||||
|
static inline void cpuidle_pause(void) { }
|
||||||
|
static inline void cpuidle_resume(void) { }
|
||||||
static inline int cpuidle_enable_device(struct cpuidle_device *dev)
|
static inline int cpuidle_enable_device(struct cpuidle_device *dev)
|
||||||
{return -ENODEV; }
|
{return -ENODEV; }
|
||||||
static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
|
static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
|
||||||
|
@ -202,14 +210,7 @@ struct cpuidle_governor {
|
||||||
extern int cpuidle_register_governor(struct cpuidle_governor *gov);
|
extern int cpuidle_register_governor(struct cpuidle_governor *gov);
|
||||||
extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
|
extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
|
||||||
|
|
||||||
#ifdef CONFIG_INTEL_IDLE
|
|
||||||
extern int intel_idle_cpu_init(int cpu);
|
|
||||||
#else
|
#else
|
||||||
static inline int intel_idle_cpu_init(int cpu) { return -1; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
static inline int intel_idle_cpu_init(int cpu) { return -1; }
|
|
||||||
|
|
||||||
static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
|
static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
|
||||||
{return 0;}
|
{return 0;}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче