diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 629023240ece..483455c5bb02 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -2105,3 +2105,46 @@ int prom_update_property(struct device_node *np, | |||
2105 | return 0; | 2105 | return 0; |
2106 | } | 2106 | } |
2107 | 2107 | ||
2108 | |||
2109 | /* Find the device node for a given logical cpu number, also returns the cpu | ||
2110 | * local thread number (index in ibm,interrupt-server#s) if relevant and | ||
2111 | * asked for (non NULL) | ||
2112 | */ | ||
2113 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | ||
2114 | { | ||
2115 | int hardid; | ||
2116 | struct device_node *np; | ||
2117 | |||
2118 | hardid = get_hard_smp_processor_id(cpu); | ||
2119 | |||
2120 | for_each_node_by_type(np, "cpu") { | ||
2121 | u32 *intserv; | ||
2122 | unsigned int plen, t; | ||
2123 | |||
2124 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist | ||
2125 | * fallback to "reg" property and assume no threads | ||
2126 | */ | ||
2127 | intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", | ||
2128 | &plen); | ||
2129 | if (intserv == NULL) { | ||
2130 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | ||
2131 | if (reg == NULL) | ||
2132 | continue; | ||
2133 | if (*reg == hardid) { | ||
2134 | if (thread) | ||
2135 | *thread = 0; | ||
2136 | return np; | ||
2137 | } | ||
2138 | } else { | ||
2139 | plen /= sizeof(u32); | ||
2140 | for (t = 0; t < plen; t++) { | ||
2141 | if (hardid == intserv[t]) { | ||
2142 | if (thread) | ||
2143 | *thread = t; | ||
2144 | return np; | ||
2145 | } | ||
2146 | } | ||
2147 | } | ||
2148 | } | ||
2149 | return NULL; | ||
2150 | } | ||