summaryrefslogtreecommitdiff
path: root/drivers/cpufreq/speedstep-centrino.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/cpufreq/speedstep-centrino.c
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/cpufreq/speedstep-centrino.c')
-rw-r--r--drivers/cpufreq/speedstep-centrino.c84
1 files changed, 73 insertions, 11 deletions
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index 4e1daca..f897d51 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -343,7 +343,9 @@ static unsigned int get_cur_freq(unsigned int cpu)
static int centrino_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
+ unsigned freq;
unsigned l, h;
+ int ret;
int i;
/* Only Intel makes Enhanced Speedstep-capable CPUs */
@@ -371,8 +373,9 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
return -ENODEV;
}
- if (centrino_cpu_init_table(policy))
+ if (centrino_cpu_init_table(policy)) {
return -ENODEV;
+ }
/* Check to see if Enhanced SpeedStep is enabled, and try to
enable it if not. */
@@ -392,11 +395,22 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
}
}
+ freq = get_cur_freq(policy->cpu);
policy->cpuinfo.transition_latency = 10000;
/* 10uS transition latency */
+ policy->cur = freq;
+
+ pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur);
- return cpufreq_table_validate_and_show(policy,
+ ret = cpufreq_frequency_table_cpuinfo(policy,
per_cpu(centrino_model, policy->cpu)->op_points);
+ if (ret)
+ return (ret);
+
+ cpufreq_frequency_table_get_attr(
+ per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu);
+
+ return 0;
}
static int centrino_cpu_exit(struct cpufreq_policy *policy)
@@ -414,18 +428,36 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
}
/**
+ * centrino_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Limit must be within this model's frequency range at least one
+ * border included.
+ */
+static int centrino_verify (struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ per_cpu(centrino_model, policy->cpu)->op_points);
+}
+
+/**
* centrino_setpolicy - set a new CPUFreq policy
* @policy: new policy
- * @index: index of target frequency
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency
+ * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
-static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
+static int centrino_target (struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
{
+ unsigned int newstate = 0;
unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu;
+ struct cpufreq_freqs freqs;
int retval = 0;
- unsigned int j, first_cpu;
- struct cpufreq_frequency_table *op_points;
+ unsigned int j, first_cpu, tmp;
cpumask_var_t covered_cpus;
if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
@@ -436,8 +468,16 @@ static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
goto out;
}
+ if (unlikely(cpufreq_frequency_table_target(policy,
+ per_cpu(centrino_model, cpu)->op_points,
+ target_freq,
+ relation,
+ &newstate))) {
+ retval = -EINVAL;
+ goto out;
+ }
+
first_cpu = 1;
- op_points = &per_cpu(centrino_model, cpu)->op_points[index];
for_each_cpu(j, policy->cpus) {
int good_cpu;
@@ -461,7 +501,7 @@ static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
break;
}
- msr = op_points->driver_data;
+ msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data;
if (first_cpu) {
rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
@@ -472,6 +512,15 @@ static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
goto out;
}
+ freqs.old = extract_clock(oldmsr, cpu, 0);
+ freqs.new = extract_clock(msr, cpu, 0);
+
+ pr_debug("target=%dkHz old=%d new=%d msr=%04x\n",
+ target_freq, freqs.old, freqs.new, msr);
+
+ cpufreq_notify_transition(policy, &freqs,
+ CPUFREQ_PRECHANGE);
+
first_cpu = 0;
/* all but 16 LSB are reserved, treat them with care */
oldmsr &= ~0xffff;
@@ -486,6 +535,8 @@ static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
cpumask_set_cpu(j, covered_cpus);
}
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+
if (unlikely(retval)) {
/*
* We have failed halfway through the frequency change.
@@ -496,6 +547,12 @@ static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
for_each_cpu(j, covered_cpus)
wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h);
+
+ tmp = freqs.new;
+ freqs.new = freqs.old;
+ freqs.old = tmp;
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
}
retval = 0;
@@ -504,15 +561,20 @@ out:
return retval;
}
+static struct freq_attr* centrino_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
static struct cpufreq_driver centrino_driver = {
.name = "centrino", /* should be speedstep-centrino,
but there's a 16 char limit */
.init = centrino_cpu_init,
.exit = centrino_cpu_exit,
- .verify = cpufreq_generic_frequency_table_verify,
- .target_index = centrino_target,
+ .verify = centrino_verify,
+ .target = centrino_target,
.get = get_cur_freq,
- .attr = cpufreq_generic_attr,
+ .attr = centrino_attr,
};
/*