aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-11-23 12:38:44 +0000
committerJon Medhurst <tixy@linaro.org>2013-04-29 09:43:51 +0100
commit66756546bd6f86dfe11a1d69559c29b201e8bdf8 (patch)
treeb57d84808cc256df3540e50efdf67782ef2362e9 /drivers
parentbbdd94fe02e9bc54b5c8d873e7dfc0ef3c592aaa (diff)
cpufreq: vexpress: Use CPU topology for mapping cpus to clusters
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/Kconfig.arm1
-rw-r--r--drivers/cpufreq/vexpress_bL_cpufreq.c42
2 files changed, 11 insertions, 32 deletions
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 4476f3a7901..2d4983aa23b 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -117,6 +117,7 @@ config ARM_HIGHBANK_CPUFREQ
config ARM_VEXPRESS_BL_CPUFREQ
tristate "CPUfreq driver for ARM Vexpress big.LITTLE CPUs"
depends on ARCH_VEXPRESS && CPU_FREQ
+ depends on ARM_CPU_TOPOLOGY
help
This enables the CPUfreq driver for ARM Vexpress big.LITTLE
platform.
diff --git a/drivers/cpufreq/vexpress_bL_cpufreq.c b/drivers/cpufreq/vexpress_bL_cpufreq.c
index 5718bbecd98..39825354b47 100644
--- a/drivers/cpufreq/vexpress_bL_cpufreq.c
+++ b/drivers/cpufreq/vexpress_bL_cpufreq.c
@@ -30,49 +30,27 @@
#include <linux/vexpress.h>
+#include <asm/topology.h>
+
#define VEXPRESS_MAX_CLUSTER 2
static struct cpufreq_frequency_table *freq_table[VEXPRESS_MAX_CLUSTER];
static atomic_t freq_table_users = ATOMIC_INIT(0);
-/* Cached current cluster for each CPU to save on IPIs */
-static DEFINE_PER_CPU(unsigned int, cpu_cur_cluster);
-
/*
* Functions to get the current status.
*
* Beware that the cluster for another CPU may change unexpectedly.
*/
-
-static unsigned int get_local_cluster(void)
-{
- unsigned int mpidr;
- asm ("mrc\tp15, 0, %0, c0, c0, 5" : "=r" (mpidr));
- return (mpidr >> 8) & 0xf;
-}
-
-static void __get_current_cluster(void *_data)
-{
- unsigned int *_cluster = _data;
- *_cluster = get_local_cluster();
-}
-
-static int get_current_cluster(unsigned int cpu)
+static int cpu_to_cluster(int cpu)
{
- unsigned int cluster = 0;
- smp_call_function_single(cpu, __get_current_cluster, &cluster, 1);
- return cluster;
-}
-
-static int get_current_cached_cluster(unsigned int cpu)
-{
- return per_cpu(cpu_cur_cluster, cpu);
+ return topology_physical_package_id(cpu);
}
/* Validate policy frequency range */
static int vexpress_cpufreq_verify_policy(struct cpufreq_policy *policy)
{
- uint32_t cur_cluster = get_current_cached_cluster(policy->cpu);
+ uint32_t cur_cluster = cpu_to_cluster(policy->cpu);
/* This call takes care of it all using freq_table */
return cpufreq_frequency_table_verify(policy, freq_table[cur_cluster]);
@@ -89,7 +67,9 @@ static int vexpress_cpufreq_set_target(struct cpufreq_policy *policy,
int ret = 0;
/* Read current clock rate */
- cur_cluster = get_current_cached_cluster(cpu);
+
+ /* ASSUMPTION: The cpu can't be hotplugged in this function */
+ cur_cluster = cpu_to_cluster(policy->cpu);
if (vexpress_spc_get_performance(cur_cluster, &freqs.old))
return -EIO;
@@ -133,7 +113,7 @@ static int vexpress_cpufreq_set_target(struct cpufreq_policy *policy,
static unsigned int vexpress_cpufreq_get(unsigned int cpu)
{
uint32_t freq = 0;
- uint32_t cur_cluster = get_current_cached_cluster(cpu);
+ uint32_t cur_cluster = cpu_to_cluster(cpu);
/*
* Read current clock rate with vexpress_spc call
@@ -207,7 +187,7 @@ free_mem:
static int vexpress_cpufreq_init(struct cpufreq_policy *policy)
{
int result = 0;
- uint32_t cur_cluster = get_current_cluster(policy->cpu);
+ uint32_t cur_cluster = cpu_to_cluster(policy->cpu);
if (atomic_inc_return(&freq_table_users) == 1)
result = vexpress_cpufreq_of_init();
@@ -228,8 +208,6 @@ static int vexpress_cpufreq_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(freq_table[cur_cluster], policy->cpu);
- per_cpu(cpu_cur_cluster, policy->cpu) = cur_cluster;
-
/* set default policy and cpuinfo */
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;