Merge branch 'idle-release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6
* 'idle-release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6: x86 idle: deprecate mwait_idle() and "idle=mwait" cmdline param x86 idle: deprecate "no-hlt" cmdline param x86 idle APM: deprecate CONFIG_APM_CPU_IDLE x86 idle floppy: deprecate disable_hlt() x86 idle: EXPORT_SYMBOL(default_idle, pm_idle) only when APM demands it x86 idle: clarify AMD erratum 400 workaround idle governor: Avoid lock acquisition to read pm_qos before entering idle cpuidle: menu: fixed wrapping timers at 4.294 seconds
This commit is contained in:
@@ -6,6 +6,42 @@ be removed from this file.
|
|||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
What: x86 floppy disable_hlt
|
||||||
|
When: 2012
|
||||||
|
Why: ancient workaround of dubious utility clutters the
|
||||||
|
code used by everybody else.
|
||||||
|
Who: Len Brown <len.brown@intel.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
|
||||||
|
When: 2012
|
||||||
|
Why: This optional sub-feature of APM is of dubious reliability,
|
||||||
|
and ancient APM laptops are likely better served by calling HLT.
|
||||||
|
Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
|
||||||
|
the pm_idle function pointer to modules.
|
||||||
|
Who: Len Brown <len.brown@intel.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
What: x86_32 "no-hlt" cmdline param
|
||||||
|
When: 2012
|
||||||
|
Why: remove a branch from idle path, simplify code used by everybody.
|
||||||
|
This option disabled the use of HLT in idle and machine_halt()
|
||||||
|
for hardware that was flakey 15-years ago. Today we have
|
||||||
|
"idle=poll" that removed HLT from idle, and so if such a machine
|
||||||
|
is still running the upstream kernel, "idle=poll" is likely sufficient.
|
||||||
|
Who: Len Brown <len.brown@intel.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
What: x86 "idle=mwait" cmdline param
|
||||||
|
When: 2012
|
||||||
|
Why: simplify x86 idle code
|
||||||
|
Who: Len Brown <len.brown@intel.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
What: PRISM54
|
What: PRISM54
|
||||||
When: 2.6.34
|
When: 2.6.34
|
||||||
|
|
||||||
|
@@ -139,7 +139,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
|
|||||||
boot_cpu_data.x86_model <= 0x05 &&
|
boot_cpu_data.x86_model <= 0x05 &&
|
||||||
boot_cpu_data.x86_mask < 0x0A)
|
boot_cpu_data.x86_mask < 0x0A)
|
||||||
return 1;
|
return 1;
|
||||||
else if (c1e_detected)
|
else if (amd_e400_c1e_detected)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return max_cstate;
|
return max_cstate;
|
||||||
|
@@ -16,6 +16,6 @@ static inline void enter_idle(void) { }
|
|||||||
static inline void exit_idle(void) { }
|
static inline void exit_idle(void) { }
|
||||||
#endif /* CONFIG_X86_64 */
|
#endif /* CONFIG_X86_64 */
|
||||||
|
|
||||||
void c1e_remove_cpu(int cpu);
|
void amd_e400_remove_cpu(int cpu);
|
||||||
|
|
||||||
#endif /* _ASM_X86_IDLE_H */
|
#endif /* _ASM_X86_IDLE_H */
|
||||||
|
@@ -754,10 +754,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
|
|||||||
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
|
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
|
||||||
|
|
||||||
extern void select_idle_routine(const struct cpuinfo_x86 *c);
|
extern void select_idle_routine(const struct cpuinfo_x86 *c);
|
||||||
extern void init_c1e_mask(void);
|
extern void init_amd_e400_c1e_mask(void);
|
||||||
|
|
||||||
extern unsigned long boot_option_idle_override;
|
extern unsigned long boot_option_idle_override;
|
||||||
extern bool c1e_detected;
|
extern bool amd_e400_c1e_detected;
|
||||||
|
|
||||||
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
|
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
|
||||||
IDLE_POLL, IDLE_FORCE_MWAIT};
|
IDLE_POLL, IDLE_FORCE_MWAIT};
|
||||||
|
@@ -361,6 +361,7 @@ struct apm_user {
|
|||||||
* idle percentage above which bios idle calls are done
|
* idle percentage above which bios idle calls are done
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_APM_CPU_IDLE
|
#ifdef CONFIG_APM_CPU_IDLE
|
||||||
|
#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012
|
||||||
#define DEFAULT_IDLE_THRESHOLD 95
|
#define DEFAULT_IDLE_THRESHOLD 95
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_IDLE_THRESHOLD 100
|
#define DEFAULT_IDLE_THRESHOLD 100
|
||||||
@@ -904,6 +905,7 @@ static void apm_cpu_idle(void)
|
|||||||
unsigned int jiffies_since_last_check = jiffies - last_jiffies;
|
unsigned int jiffies_since_last_check = jiffies - last_jiffies;
|
||||||
unsigned int bucket;
|
unsigned int bucket;
|
||||||
|
|
||||||
|
WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012");
|
||||||
recalc:
|
recalc:
|
||||||
if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
|
if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
|
||||||
use_apm_idle = 0;
|
use_apm_idle = 0;
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
static int __init no_halt(char *s)
|
static int __init no_halt(char *s)
|
||||||
{
|
{
|
||||||
|
WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n");
|
||||||
boot_cpu_data.hlt_works_ok = 0;
|
boot_cpu_data.hlt_works_ok = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -902,7 +902,7 @@ static void vgetcpu_set_mode(void)
|
|||||||
void __init identify_boot_cpu(void)
|
void __init identify_boot_cpu(void)
|
||||||
{
|
{
|
||||||
identify_cpu(&boot_cpu_data);
|
identify_cpu(&boot_cpu_data);
|
||||||
init_c1e_mask();
|
init_amd_e400_c1e_mask();
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
sysenter_setup();
|
sysenter_setup();
|
||||||
enable_sep_cpu();
|
enable_sep_cpu();
|
||||||
|
@@ -337,7 +337,9 @@ EXPORT_SYMBOL(boot_option_idle_override);
|
|||||||
* Powermanagement idle function, if any..
|
* Powermanagement idle function, if any..
|
||||||
*/
|
*/
|
||||||
void (*pm_idle)(void);
|
void (*pm_idle)(void);
|
||||||
|
#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
|
||||||
EXPORT_SYMBOL(pm_idle);
|
EXPORT_SYMBOL(pm_idle);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
/*
|
/*
|
||||||
@@ -397,7 +399,7 @@ void default_idle(void)
|
|||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_APM_MODULE
|
#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
|
||||||
EXPORT_SYMBOL(default_idle);
|
EXPORT_SYMBOL(default_idle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -535,45 +537,45 @@ int mwait_usable(const struct cpuinfo_x86 *c)
|
|||||||
return (edx & MWAIT_EDX_C1);
|
return (edx & MWAIT_EDX_C1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool c1e_detected;
|
bool amd_e400_c1e_detected;
|
||||||
EXPORT_SYMBOL(c1e_detected);
|
EXPORT_SYMBOL(amd_e400_c1e_detected);
|
||||||
|
|
||||||
static cpumask_var_t c1e_mask;
|
static cpumask_var_t amd_e400_c1e_mask;
|
||||||
|
|
||||||
void c1e_remove_cpu(int cpu)
|
void amd_e400_remove_cpu(int cpu)
|
||||||
{
|
{
|
||||||
if (c1e_mask != NULL)
|
if (amd_e400_c1e_mask != NULL)
|
||||||
cpumask_clear_cpu(cpu, c1e_mask);
|
cpumask_clear_cpu(cpu, amd_e400_c1e_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* C1E aware idle routine. We check for C1E active in the interrupt
|
* AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt
|
||||||
* pending message MSR. If we detect C1E, then we handle it the same
|
* pending message MSR. If we detect C1E, then we handle it the same
|
||||||
* way as C3 power states (local apic timer and TSC stop)
|
* way as C3 power states (local apic timer and TSC stop)
|
||||||
*/
|
*/
|
||||||
static void c1e_idle(void)
|
static void amd_e400_idle(void)
|
||||||
{
|
{
|
||||||
if (need_resched())
|
if (need_resched())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!c1e_detected) {
|
if (!amd_e400_c1e_detected) {
|
||||||
u32 lo, hi;
|
u32 lo, hi;
|
||||||
|
|
||||||
rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
|
rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
|
||||||
|
|
||||||
if (lo & K8_INTP_C1E_ACTIVE_MASK) {
|
if (lo & K8_INTP_C1E_ACTIVE_MASK) {
|
||||||
c1e_detected = true;
|
amd_e400_c1e_detected = true;
|
||||||
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
|
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
|
||||||
mark_tsc_unstable("TSC halt in AMD C1E");
|
mark_tsc_unstable("TSC halt in AMD C1E");
|
||||||
printk(KERN_INFO "System has AMD C1E enabled\n");
|
printk(KERN_INFO "System has AMD C1E enabled\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c1e_detected) {
|
if (amd_e400_c1e_detected) {
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
if (!cpumask_test_cpu(cpu, c1e_mask)) {
|
if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
|
||||||
cpumask_set_cpu(cpu, c1e_mask);
|
cpumask_set_cpu(cpu, amd_e400_c1e_mask);
|
||||||
/*
|
/*
|
||||||
* Force broadcast so ACPI can not interfere.
|
* Force broadcast so ACPI can not interfere.
|
||||||
*/
|
*/
|
||||||
@@ -616,17 +618,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
|
|||||||
pm_idle = mwait_idle;
|
pm_idle = mwait_idle;
|
||||||
} else if (cpu_has_amd_erratum(amd_erratum_400)) {
|
} else if (cpu_has_amd_erratum(amd_erratum_400)) {
|
||||||
/* E400: APIC timer interrupt does not wake up CPU from C1e */
|
/* E400: APIC timer interrupt does not wake up CPU from C1e */
|
||||||
printk(KERN_INFO "using C1E aware idle routine\n");
|
printk(KERN_INFO "using AMD E400 aware idle routine\n");
|
||||||
pm_idle = c1e_idle;
|
pm_idle = amd_e400_idle;
|
||||||
} else
|
} else
|
||||||
pm_idle = default_idle;
|
pm_idle = default_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init init_c1e_mask(void)
|
void __init init_amd_e400_c1e_mask(void)
|
||||||
{
|
{
|
||||||
/* If we're using c1e_idle, we need to allocate c1e_mask. */
|
/* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */
|
||||||
if (pm_idle == c1e_idle)
|
if (pm_idle == amd_e400_idle)
|
||||||
zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
|
zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init idle_setup(char *str)
|
static int __init idle_setup(char *str)
|
||||||
@@ -640,6 +642,7 @@ static int __init idle_setup(char *str)
|
|||||||
boot_option_idle_override = IDLE_POLL;
|
boot_option_idle_override = IDLE_POLL;
|
||||||
} else if (!strcmp(str, "mwait")) {
|
} else if (!strcmp(str, "mwait")) {
|
||||||
boot_option_idle_override = IDLE_FORCE_MWAIT;
|
boot_option_idle_override = IDLE_FORCE_MWAIT;
|
||||||
|
WARN_ONCE(1, "\idle=mwait\" will be removed in 2012\"\n");
|
||||||
} else if (!strcmp(str, "halt")) {
|
} else if (!strcmp(str, "halt")) {
|
||||||
/*
|
/*
|
||||||
* When the boot option of idle=halt is added, halt is
|
* When the boot option of idle=halt is added, halt is
|
||||||
|
@@ -1307,7 +1307,7 @@ void play_dead_common(void)
|
|||||||
{
|
{
|
||||||
idle_task_exit();
|
idle_task_exit();
|
||||||
reset_lazy_tlbstate();
|
reset_lazy_tlbstate();
|
||||||
c1e_remove_cpu(raw_smp_processor_id());
|
amd_e400_remove_cpu(raw_smp_processor_id());
|
||||||
|
|
||||||
mb();
|
mb();
|
||||||
/* Ack it */
|
/* Ack it */
|
||||||
|
@@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
|||||||
if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
|
if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (c1e_detected)
|
if (amd_e400_c1e_detected)
|
||||||
type = ACPI_STATE_C1;
|
type = ACPI_STATE_C1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1038,6 +1038,7 @@ static void floppy_disable_hlt(void)
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012");
|
||||||
spin_lock_irqsave(&floppy_hlt_lock, flags);
|
spin_lock_irqsave(&floppy_hlt_lock, flags);
|
||||||
if (!hlt_disabled) {
|
if (!hlt_disabled) {
|
||||||
hlt_disabled = 1;
|
hlt_disabled = 1;
|
||||||
|
@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev)
|
|||||||
unsigned int power_usage = -1;
|
unsigned int power_usage = -1;
|
||||||
int i;
|
int i;
|
||||||
int multiplier;
|
int multiplier;
|
||||||
|
struct timespec t;
|
||||||
|
|
||||||
if (data->needs_update) {
|
if (data->needs_update) {
|
||||||
menu_update(dev);
|
menu_update(dev);
|
||||||
@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* determine the expected residency time, round up */
|
/* determine the expected residency time, round up */
|
||||||
|
t = ktime_to_timespec(tick_nohz_get_sleep_length());
|
||||||
data->expected_us =
|
data->expected_us =
|
||||||
DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000);
|
t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC;
|
||||||
|
|
||||||
|
|
||||||
data->bucket = which_bucket(data->expected_us);
|
data->bucket = which_bucket(data->expected_us);
|
||||||
|
@@ -16,6 +16,10 @@
|
|||||||
#define PM_QOS_NUM_CLASSES 4
|
#define PM_QOS_NUM_CLASSES 4
|
||||||
#define PM_QOS_DEFAULT_VALUE -1
|
#define PM_QOS_DEFAULT_VALUE -1
|
||||||
|
|
||||||
|
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||||
|
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||||
|
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
|
||||||
|
|
||||||
struct pm_qos_request_list {
|
struct pm_qos_request_list {
|
||||||
struct plist_node list;
|
struct plist_node list;
|
||||||
int pm_qos_class;
|
int pm_qos_class;
|
||||||
|
@@ -54,11 +54,17 @@ enum pm_qos_type {
|
|||||||
PM_QOS_MIN /* return the smallest value */
|
PM_QOS_MIN /* return the smallest value */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: The lockless read path depends on the CPU accessing
|
||||||
|
* target_value atomically. Atomic access is only guaranteed on all CPU
|
||||||
|
* types linux supports for 32 bit quantites
|
||||||
|
*/
|
||||||
struct pm_qos_object {
|
struct pm_qos_object {
|
||||||
struct plist_head requests;
|
struct plist_head requests;
|
||||||
struct blocking_notifier_head *notifiers;
|
struct blocking_notifier_head *notifiers;
|
||||||
struct miscdevice pm_qos_power_miscdev;
|
struct miscdevice pm_qos_power_miscdev;
|
||||||
char *name;
|
char *name;
|
||||||
|
s32 target_value; /* Do not change to 64 bit */
|
||||||
s32 default_value;
|
s32 default_value;
|
||||||
enum pm_qos_type type;
|
enum pm_qos_type type;
|
||||||
};
|
};
|
||||||
@@ -71,7 +77,8 @@ static struct pm_qos_object cpu_dma_pm_qos = {
|
|||||||
.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
|
.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
|
||||||
.notifiers = &cpu_dma_lat_notifier,
|
.notifiers = &cpu_dma_lat_notifier,
|
||||||
.name = "cpu_dma_latency",
|
.name = "cpu_dma_latency",
|
||||||
.default_value = 2000 * USEC_PER_SEC,
|
.target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
|
||||||
|
.default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
|
||||||
.type = PM_QOS_MIN,
|
.type = PM_QOS_MIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,7 +87,8 @@ static struct pm_qos_object network_lat_pm_qos = {
|
|||||||
.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
|
.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
|
||||||
.notifiers = &network_lat_notifier,
|
.notifiers = &network_lat_notifier,
|
||||||
.name = "network_latency",
|
.name = "network_latency",
|
||||||
.default_value = 2000 * USEC_PER_SEC,
|
.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
|
||||||
|
.default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
|
||||||
.type = PM_QOS_MIN
|
.type = PM_QOS_MIN
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,7 +98,8 @@ static struct pm_qos_object network_throughput_pm_qos = {
|
|||||||
.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
|
.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
|
||||||
.notifiers = &network_throughput_notifier,
|
.notifiers = &network_throughput_notifier,
|
||||||
.name = "network_throughput",
|
.name = "network_throughput",
|
||||||
.default_value = 0,
|
.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
|
||||||
|
.default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
|
||||||
.type = PM_QOS_MAX,
|
.type = PM_QOS_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -136,6 +145,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline s32 pm_qos_read_value(struct pm_qos_object *o)
|
||||||
|
{
|
||||||
|
return o->target_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
|
||||||
|
{
|
||||||
|
o->target_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void update_target(struct pm_qos_object *o, struct plist_node *node,
|
static void update_target(struct pm_qos_object *o, struct plist_node *node,
|
||||||
int del, int value)
|
int del, int value)
|
||||||
{
|
{
|
||||||
@@ -160,6 +179,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
|
|||||||
plist_add(node, &o->requests);
|
plist_add(node, &o->requests);
|
||||||
}
|
}
|
||||||
curr_value = pm_qos_get_value(o);
|
curr_value = pm_qos_get_value(o);
|
||||||
|
pm_qos_set_value(o, curr_value);
|
||||||
spin_unlock_irqrestore(&pm_qos_lock, flags);
|
spin_unlock_irqrestore(&pm_qos_lock, flags);
|
||||||
|
|
||||||
if (prev_value != curr_value)
|
if (prev_value != curr_value)
|
||||||
@@ -194,18 +214,11 @@ static int find_pm_qos_object_by_minor(int minor)
|
|||||||
* pm_qos_request - returns current system wide qos expectation
|
* pm_qos_request - returns current system wide qos expectation
|
||||||
* @pm_qos_class: identification of which qos value is requested
|
* @pm_qos_class: identification of which qos value is requested
|
||||||
*
|
*
|
||||||
* This function returns the current target value in an atomic manner.
|
* This function returns the current target value.
|
||||||
*/
|
*/
|
||||||
int pm_qos_request(int pm_qos_class)
|
int pm_qos_request(int pm_qos_class)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
return pm_qos_read_value(pm_qos_array[pm_qos_class]);
|
||||||
int value;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pm_qos_lock, flags);
|
|
||||||
value = pm_qos_get_value(pm_qos_array[pm_qos_class]);
|
|
||||||
spin_unlock_irqrestore(&pm_qos_lock, flags);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pm_qos_request);
|
EXPORT_SYMBOL_GPL(pm_qos_request);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user