aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c2
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c2
-rw-r--r--drivers/cpufreq/powernow-k8.c63
3 files changed, 36 insertions, 31 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index b75dc2c2f8d3..a152af7e1991 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -466,7 +466,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
466 delay -= jiffies % delay; 466 delay -= jiffies % delay;
467 467
468 dbs_info->enable = 1; 468 dbs_info->enable = 1;
469 INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); 469 INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer);
470 schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); 470 schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
471} 471}
472 472
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 9479fb33c30f..396322f2a83f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -644,7 +644,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
644 delay -= jiffies % delay; 644 delay -= jiffies % delay;
645 645
646 dbs_info->sample_type = DBS_NORMAL_SAMPLE; 646 dbs_info->sample_type = DBS_NORMAL_SAMPLE;
647 INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); 647 INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer);
648 schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); 648 schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
649} 649}
650 650
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 0b19faf002ee..129e80bfff22 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -35,7 +35,6 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/string.h> 36#include <linux/string.h>
37#include <linux/cpumask.h> 37#include <linux/cpumask.h>
38#include <linux/sched.h> /* for current / set_cpus_allowed() */
39#include <linux/io.h> 38#include <linux/io.h>
40#include <linux/delay.h> 39#include <linux/delay.h>
41 40
@@ -978,16 +977,23 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
978 return res; 977 return res;
979} 978}
980 979
981/* Driver entry point to switch to the target frequency */ 980struct powernowk8_target_arg {
982static int powernowk8_target(struct cpufreq_policy *pol, 981 struct cpufreq_policy *pol;
983 unsigned targfreq, unsigned relation) 982 unsigned targfreq;
983 unsigned relation;
984};
985
986static long powernowk8_target_fn(void *arg)
984{ 987{
985 cpumask_var_t oldmask; 988 struct powernowk8_target_arg *pta = arg;
989 struct cpufreq_policy *pol = pta->pol;
990 unsigned targfreq = pta->targfreq;
991 unsigned relation = pta->relation;
986 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); 992 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
987 u32 checkfid; 993 u32 checkfid;
988 u32 checkvid; 994 u32 checkvid;
989 unsigned int newstate; 995 unsigned int newstate;
990 int ret = -EIO; 996 int ret;
991 997
992 if (!data) 998 if (!data)
993 return -EINVAL; 999 return -EINVAL;
@@ -995,29 +1001,16 @@ static int powernowk8_target(struct cpufreq_policy *pol,
995 checkfid = data->currfid; 1001 checkfid = data->currfid;
996 checkvid = data->currvid; 1002 checkvid = data->currvid;
997 1003
998 /* only run on specific CPU from here on. */
999 /* This is poor form: use a workqueue or smp_call_function_single */
1000 if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
1001 return -ENOMEM;
1002
1003 cpumask_copy(oldmask, tsk_cpus_allowed(current));
1004 set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
1005
1006 if (smp_processor_id() != pol->cpu) {
1007 printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
1008 goto err_out;
1009 }
1010
1011 if (pending_bit_stuck()) { 1004 if (pending_bit_stuck()) {
1012 printk(KERN_ERR PFX "failing targ, change pending bit set\n"); 1005 printk(KERN_ERR PFX "failing targ, change pending bit set\n");
1013 goto err_out; 1006 return -EIO;
1014 } 1007 }
1015 1008
1016 pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", 1009 pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
1017 pol->cpu, targfreq, pol->min, pol->max, relation); 1010 pol->cpu, targfreq, pol->min, pol->max, relation);
1018 1011
1019 if (query_current_values_with_pending_wait(data)) 1012 if (query_current_values_with_pending_wait(data))
1020 goto err_out; 1013 return -EIO;
1021 1014
1022 pr_debug("targ: curr fid 0x%x, vid 0x%x\n", 1015 pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
1023 data->currfid, data->currvid); 1016 data->currfid, data->currvid);
@@ -1032,7 +1025,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
1032 1025
1033 if (cpufreq_frequency_table_target(pol, data->powernow_table, 1026 if (cpufreq_frequency_table_target(pol, data->powernow_table,
1034 targfreq, relation, &newstate)) 1027 targfreq, relation, &newstate))
1035 goto err_out; 1028 return -EIO;
1036 1029
1037 mutex_lock(&fidvid_mutex); 1030 mutex_lock(&fidvid_mutex);
1038 1031
@@ -1042,19 +1035,31 @@ static int powernowk8_target(struct cpufreq_policy *pol,
1042 1035
1043 if (ret) { 1036 if (ret) {
1044 printk(KERN_ERR PFX "transition frequency failed\n"); 1037 printk(KERN_ERR PFX "transition frequency failed\n");
1045 ret = 1;
1046 mutex_unlock(&fidvid_mutex); 1038 mutex_unlock(&fidvid_mutex);
1047 goto err_out; 1039 return 1;
1048 } 1040 }
1049 mutex_unlock(&fidvid_mutex); 1041 mutex_unlock(&fidvid_mutex);
1050 1042
1051 pol->cur = find_khz_freq_from_fid(data->currfid); 1043 pol->cur = find_khz_freq_from_fid(data->currfid);
1052 ret = 0;
1053 1044
1054err_out: 1045 return 0;
1055 set_cpus_allowed_ptr(current, oldmask); 1046}
1056 free_cpumask_var(oldmask); 1047
1057 return ret; 1048/* Driver entry point to switch to the target frequency */
1049static int powernowk8_target(struct cpufreq_policy *pol,
1050 unsigned targfreq, unsigned relation)
1051{
1052 struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
1053 .relation = relation };
1054
1055 /*
1056 * Must run on @pol->cpu. cpufreq core is responsible for ensuring
1057 * that we're bound to the current CPU and pol->cpu stays online.
1058 */
1059 if (smp_processor_id() == pol->cpu)
1060 return powernowk8_target_fn(&pta);
1061 else
1062 return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
1058} 1063}
1059 1064
1060/* Driver entry point to verify the policy and range of frequencies */ 1065/* Driver entry point to verify the policy and range of frequencies */