summaryrefslogtreecommitdiff
path: root/drivers/acpi/processor_throttling.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_throttling.c')
-rw-r--r--drivers/acpi/processor_throttling.c100
1 files changed, 50 insertions, 50 deletions
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 227543789ba9..aed7e308ff72 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -74,7 +74,7 @@ static int acpi_processor_update_tsd_coord(void)
struct acpi_tsd_package *pdomain, *match_pdomain;
struct acpi_processor_throttling *pthrottling, *match_pthrottling;
- if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
return -ENOMEM;
/*
@@ -102,7 +102,6 @@ static int acpi_processor_update_tsd_coord(void)
if (retval)
goto err_ret;
- cpumask_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
if (!pr)
@@ -617,6 +616,8 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
u32 duty_mask = 0;
u32 duty_value = 0;
+ WARN_ON_ONCE(!irqs_disabled());
+
if (!pr)
return -EINVAL;
@@ -629,8 +630,6 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
duty_mask <<= pr->throttling.duty_offset;
- local_irq_disable();
-
value = inl(pr->throttling.address);
/*
@@ -647,8 +646,6 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
pr->throttling.state = state;
- local_irq_enable();
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Throttling state is T%d (%d%% throttling applied)\n",
state, pr->throttling.states[state].performance));
@@ -852,10 +849,21 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
return 0;
}
+struct get_throttling {
+ struct acpi_processor *pr;
+ int ret;
+};
+
+static void get_throttling(void *_gt)
+{
+ struct get_throttling *gt = _gt;
+
+ gt->ret = gt->pr->throttling.acpi_processor_get_throttling(gt->pr);
+}
+
static int acpi_processor_get_throttling(struct acpi_processor *pr)
{
- cpumask_var_t saved_mask;
- int ret;
+ struct get_throttling gt;
if (!pr)
return -EINVAL;
@@ -863,21 +871,9 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
if (!pr->flags.throttling)
return -ENODEV;
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
- return -ENOMEM;
-
- /*
- * Migrate task to the cpu pointed by pr.
- */
- cpumask_copy(saved_mask, &current->cpus_allowed);
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(pr->id));
- ret = pr->throttling.acpi_processor_get_throttling(pr);
- /* restore the previous state */
- set_cpus_allowed_ptr(current, saved_mask);
- free_cpumask_var(saved_mask);
-
- return ret;
+ gt.pr = pr;
+ smp_call_function_single(pr->id, get_throttling, &gt, 1);
+ return gt.ret;
}
static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
@@ -921,6 +917,8 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
u32 duty_mask = 0;
u32 duty_value = 0;
+ WARN_ON_ONCE(!irqs_disabled());
+
if (!pr)
return -EINVAL;
@@ -950,8 +948,6 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
duty_mask = ~duty_mask;
}
- local_irq_disable();
-
/*
* Disable throttling by writing a 0 to bit 4. Note that we must
* turn it off before you can change the duty_value.
@@ -977,8 +973,6 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
pr->throttling.state = state;
- local_irq_enable();
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Throttling state set to T%d (%d%%)\n", state,
(pr->throttling.states[state].performance ? pr->
@@ -1018,9 +1012,23 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
return 0;
}
+struct set_throttling_info {
+ struct acpi_processor *pr;
+ struct acpi_processor_throttling *p_throttling;
+ int target_state;
+ int ret;
+};
+
+static void set_throttling(void *_sti)
+{
+ struct set_throttling_info *s = _sti;
+
+ s->ret = s->p_throttling->acpi_processor_set_throttling(s->pr,
+ s->target_state);
+}
+
int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
{
- cpumask_var_t saved_mask;
int ret = 0;
unsigned int i;
struct acpi_processor *match_pr;
@@ -1037,15 +1045,9 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
if ((state < 0) || (state > (pr->throttling.state_count - 1)))
return -EINVAL;
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
+ if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL))
return -ENOMEM;
- if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) {
- free_cpumask_var(saved_mask);
- return -ENOMEM;
- }
-
- cpumask_copy(saved_mask, &current->cpus_allowed);
t_state.target_state = state;
p_throttling = &(pr->throttling);
cpumask_and(online_throttling_cpus, cpu_online_mask,
@@ -1067,10 +1069,10 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* it can be called only for the cpu pointed by pr.
*/
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(pr->id));
- ret = p_throttling->acpi_processor_set_throttling(pr,
- t_state.target_state);
+ struct set_throttling_info sti
+ = { pr, p_throttling, t_state.target_state };
+ smp_call_function_single(pr->id, set_throttling, &sti, 1);
+ ret = sti.ret;
} else {
/*
* When the T-state coordination is SW_ALL or HW_ALL,
@@ -1078,6 +1080,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* cpus.
*/
for_each_cpu(i, online_throttling_cpus) {
+ struct set_throttling_info sti;
+
match_pr = per_cpu(processors, i);
/*
* If the pointer is invalid, we will report the
@@ -1099,11 +1103,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
continue;
}
t_state.cpu = i;
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(i));
- ret = match_pr->throttling.
- acpi_processor_set_throttling(
- match_pr, t_state.target_state);
+ sti.pr = match_pr;
+ sti.p_throttling = &match_pr->throttling;
+ sti.target_state = t_state.target_state;
+ smp_call_function_single(i, set_throttling, &sti, 1);
+ ret = sti.ret;
}
}
/*
@@ -1117,11 +1121,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
&t_state);
}
- /* restore the previous state */
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, saved_mask);
- free_cpumask_var(online_throttling_cpus);
- free_cpumask_var(saved_mask);
return ret;
}
@@ -1214,7 +1213,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
}
/* proc interface */
-
+#ifdef CONFIG_ACPI_PROCFS
static int acpi_processor_throttling_seq_show(struct seq_file *seq,
void *offset)
{
@@ -1322,3 +1321,4 @@ const struct file_operations acpi_processor_throttling_fops = {
.llseek = seq_lseek,
.release = single_release,
};
+#endif