aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>2013-08-15 08:34:18 -0400
committerSudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>2013-08-21 05:24:38 -0400
commit819d596568d82ffb85b0b5989a1567810fe66098 (patch)
tree3be30cd02feff35df069b36af55b77c975282f8a
parent007fb9aedc7544f67ffbdce95283b1c6c58999c3 (diff)
powerpc: refactor of_get_cpu_node to support other architectures
Currently different drivers requiring to access cpu device node are parsing the device tree themselves. Since the ordering in the DT need not match the logical cpu ordering, the parsing logic needs to consider that. However, this has resulted in lots of code duplication and in some cases even incorrect logic. It's better to consolidate them by adding support for getting cpu device node for a given logical cpu index in DT core library. However logical to physical index mapping can be architecture specific. PowerPC has it's own implementation to get the cpu node for a given logical index. This patch refactors the current implementation of of_get_cpu_node. This in preparation to move the implementation to DT core library. It separates out the logical to physical mapping so that a default matching of the physical id to the logical cpu index can be added when moved to common code. Architecture specific code can override it. Cc: Rob Herring <rob.herring@calxeda.com> Cc: Grant Likely <grant.likely@linaro.org> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
-rw-r--r--arch/powerpc/kernel/prom.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index eb23ac92abb9..f7b8c0be982e 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
865__initcall(prom_reconfig_setup); 865__initcall(prom_reconfig_setup);
866#endif 866#endif
867 867
868bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
869{
870 return (int)phys_id == get_hard_smp_processor_id(cpu);
871}
872
873static bool __of_find_n_match_cpu_property(struct device_node *cpun,
874 const char *prop_name, int cpu, unsigned int *thread)
875{
876 const __be32 *cell;
877 int ac, prop_len, tid;
878 u64 hwid;
879
880 ac = of_n_addr_cells(cpun);
881 cell = of_get_property(cpun, prop_name, &prop_len);
882 if (!cell)
883 return false;
884 prop_len /= sizeof(*cell);
885 for (tid = 0; tid < prop_len; tid++) {
886 hwid = of_read_number(cell, ac);
887 if (arch_match_cpu_phys_id(cpu, hwid)) {
888 if (thread)
889 *thread = tid;
890 return true;
891 }
892 cell += ac;
893 }
894 return false;
895}
896
868/* Find the device node for a given logical cpu number, also returns the cpu 897/* Find the device node for a given logical cpu number, also returns the cpu
869 * local thread number (index in ibm,interrupt-server#s) if relevant and 898 * local thread number (index in ibm,interrupt-server#s) if relevant and
870 * asked for (non NULL) 899 * asked for (non NULL)
871 */ 900 */
872struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 901struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
873{ 902{
874 int hardid; 903 struct device_node *cpun, *cpus;
875 struct device_node *np;
876 904
877 hardid = get_hard_smp_processor_id(cpu); 905 cpus = of_find_node_by_path("/cpus");
906 if (!cpus) {
907 pr_warn("Missing cpus node, bailing out\n");
908 return NULL;
909 }
878 910
879 for_each_node_by_type(np, "cpu") { 911 for_each_child_of_node(cpus, cpun) {
880 const u32 *intserv; 912 if (of_node_cmp(cpun->type, "cpu"))
881 unsigned int plen, t; 913 continue;
882 914
883 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist 915 /* Check for non-standard "ibm,ppc-interrupt-server#s" property
884 * fallback to "reg" property and assume no threads 916 * for thread ids on PowerPC. If it doesn't exist fallback to
917 * standard "reg" property.
885 */ 918 */
886 intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", 919 if (__of_find_n_match_cpu_property(cpun,
887 &plen); 920 "ibm,ppc-interrupt-server#s", cpu, thread))
888 if (intserv == NULL) { 921 return cpun;
889 const u32 *reg = of_get_property(np, "reg", NULL); 922
890 if (reg == NULL) 923 if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
891 continue; 924 return cpun;
892 if (*reg == hardid) {
893 if (thread)
894 *thread = 0;
895 return np;
896 }
897 } else {
898 plen /= sizeof(u32);
899 for (t = 0; t < plen; t++) {
900 if (hardid == intserv[t]) {
901 if (thread)
902 *thread = t;
903 return np;
904 }
905 }
906 }
907 } 925 }
908 return NULL; 926 return NULL;
909} 927}