diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-23 00:57:19 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-23 00:57:19 +0200 |
commit | 09198f8feff1fcdf03994f35955292f85b299bd6 (patch) | |
tree | d847a584546c13d1761036a2aae8d28437550df0 /arch/arm | |
parent | 4eb5178c9cc09295111b79a99183f555c51887b4 (diff) | |
parent | 1037b2752345cc5666e90b711a913ab2ae6c5920 (diff) |
Merge branch 'cpu_of_node' of git://linux-arm.org/linux-skn into pm-cpufreq-next
Pull DT/core/cpufreq cpu_ofnode updates for v3.12 from Sudeep KarkadaNagesha.
* 'cpu_of_node' of git://linux-arm.org/linux-skn:
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
ARM: mvebu: remove device tree parsing for cpu nodes
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
of/device: add helper to get cpu device node from logical cpu index
driver/core: cpu: initialize of_node in cpu's device struture
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
of: move of_get_cpu_node implementation to DT core library
powerpc: refactor of_get_cpu_node to support other architectures
openrisc: remove undefined of_get_cpu_node declaration
microblaze: remove undefined of_get_cpu_node declaration
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/devtree.c | 5 | ||||
-rw-r--r-- | arch/arm/kernel/topology.c | 61 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 51 |
4 files changed, 48 insertions, 72 deletions
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5859c8bc727c..2ee8a17d2b01 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void) } } +bool arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); +} + /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt_phys: physical address of dt blob diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index c5a59546a256..85a87370f144 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = { {NULL, }, }; -struct cpu_capacity { - unsigned long hwid; - unsigned long capacity; -}; - -struct cpu_capacity *cpu_capacity; +unsigned long *__cpu_capacity; +#define cpu_capacity(cpu) __cpu_capacity[cpu] unsigned long middle_capacity = 1; @@ -100,15 +96,19 @@ static void __init parse_dt_topology(void) unsigned long capacity = 0; int alloc_size, cpu = 0; - alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity); - cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); + alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity); + __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); - while ((cn = of_find_node_by_type(cn, "cpu"))) { - const u32 *rate, *reg; + for_each_possible_cpu(cpu) { + const u32 *rate; int len; - if (cpu >= num_possible_cpus()) - break; + /* too early to use cpu->of_node */ + cn = of_get_cpu_node(cpu, NULL); + if (!cn) { + pr_err("missing device node for CPU %d\n", cpu); + continue; + } for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) if (of_device_is_compatible(cn, cpu_eff->compatible)) @@ -124,12 +124,6 @@ static void __init parse_dt_topology(void) continue; } - reg = of_get_property(cn, "reg", &len); - if (!reg || len != 4) { - pr_err("%s missing reg property\n", cn->full_name); - continue; - } - capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; /* Save min capacity of the system */ @@ -140,13 +134,9 @@ static void __init parse_dt_topology(void) if (capacity > max_capacity) max_capacity = capacity; - cpu_capacity[cpu].capacity = capacity; - cpu_capacity[cpu++].hwid = be32_to_cpup(reg); + cpu_capacity(cpu) = capacity; } - if (cpu < num_possible_cpus()) - cpu_capacity[cpu].hwid = (unsigned long)(-1); - /* If min and max capacities are equals, we bypass the update of the * cpu_scale because all CPUs have the same capacity. Otherwise, we * compute a middle_capacity factor that will ensure that the capacity @@ -154,9 +144,7 @@ static void __init parse_dt_topology(void) * SCHED_POWER_SCALE, which is the default value, but with the * constraint explained near table_efficiency[]. */ - if (min_capacity == max_capacity) - cpu_capacity[0].hwid = (unsigned long)(-1); - else if (4*max_capacity < (3*(max_capacity + min_capacity))) + if (4*max_capacity < (3*(max_capacity + min_capacity))) middle_capacity = (min_capacity + max_capacity) >> (SCHED_POWER_SHIFT+1); else @@ -170,23 +158,12 @@ static void __init parse_dt_topology(void) * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the * function returns directly for SMP system. */ -void update_cpu_power(unsigned int cpu, unsigned long hwid) +void update_cpu_power(unsigned int cpu) { - unsigned int idx = 0; - - /* look for the cpu's hwid in the cpu capacity table */ - for (idx = 0; idx < num_possible_cpus(); idx++) { - if (cpu_capacity[idx].hwid == hwid) - break; - - if (cpu_capacity[idx].hwid == -1) - return; - } - - if (idx == num_possible_cpus()) + if (!cpu_capacity(cpu)) return; - set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity); + set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity); printk(KERN_INFO "CPU%u: update cpu_power %lu\n", cpu, arch_scale_freq_power(NULL, cpu)); @@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid) #else static inline void parse_dt_topology(void) {} -static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} +static inline void update_cpu_power(unsigned int cpuid) {} #endif /* @@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid) update_siblings_masks(cpuid); - update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK); + update_cpu_power(cpuid); printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", cpuid, cpu_topology[cpuid].thread_id, diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7be13f8e69a0..a02f275a198d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev) { struct device_node *np; - np = of_find_node_by_path("/cpus/cpu@0"); + np = of_node_get(cpu_dev->of_node); if (!np) { pr_warn("failed to find cpu0 node\n"); return; } - cpu_dev->of_node = np; if (of_init_opp_table(cpu_dev)) { pr_warn("failed to init OPP table\n"); goto put_node; diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index ce81d3031405..594b63db4215 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -29,45 +29,40 @@ #include "pmsu.h" #include "coherency.h" +static struct clk *__init get_cpu_clk(int cpu) +{ + struct clk *cpu_clk; + struct device_node *np = of_get_cpu_node(cpu, NULL); + + if (WARN(!np, "missing cpu node\n")) + return NULL; + cpu_clk = of_clk_get(np, 0); + if (WARN_ON(IS_ERR(cpu_clk))) + return NULL; + return cpu_clk; +} + void __init set_secondary_cpus_clock(void) { - int thiscpu; + int thiscpu, cpu; unsigned long rate; - struct clk *cpu_clk = NULL; - struct device_node *np = NULL; + struct clk *cpu_clk; thiscpu = smp_processor_id(); - for_each_node_by_type(np, "cpu") { - int err; - int cpu; - - err = of_property_read_u32(np, "reg", &cpu); - if (WARN_ON(err)) - return; - - if (cpu == thiscpu) { - cpu_clk = of_clk_get(np, 0); - break; - } - } - if (WARN_ON(IS_ERR(cpu_clk))) + cpu_clk = get_cpu_clk(thiscpu); + if (!cpu_clk) return; clk_prepare_enable(cpu_clk); rate = clk_get_rate(cpu_clk); /* set all the other CPU clk to the same rate than the boot CPU */ - for_each_node_by_type(np, "cpu") { - int err; - int cpu; - - err = of_property_read_u32(np, "reg", &cpu); - if (WARN_ON(err)) + for_each_possible_cpu(cpu) { + if (cpu == thiscpu) + continue; + cpu_clk = get_cpu_clk(cpu); + if (!cpu_clk) return; - - if (cpu != thiscpu) { - cpu_clk = of_clk_get(np, 0); - clk_set_rate(cpu_clk, rate); - } + clk_set_rate(cpu_clk, rate); } } |