aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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}