diff options
author | Christian Krafft <krafft@de.ibm.com> | 2007-04-23 15:35:46 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-04-23 15:44:40 -0400 |
commit | 9dd855a729abb4670522d5eae6854db48d624498 (patch) | |
tree | 686c5e26fc68b16822df87308d553981908d295e /arch | |
parent | 6bf05fd776e38a0a9c17e17c2345b59b1b9aa2cb (diff) |
[POWERPC] cell: add support for proper device-tree
This patch adds support for a proper device-tree.
A porper device-tree on cell contains be nodes
for each CBE containg nodes for SPEs and all the
other special devices on it.
Ofcourse oldschool devicetree is still supported.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/cell/cbe_regs.c | 118 |
1 files changed, 88 insertions, 30 deletions
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index dca39c0af7ea..12c9674b4b1f 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | #include <asm/prom.h> | 15 | #include <asm/prom.h> |
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | #include <asm/of_device.h> | ||
18 | #include <asm/of_platform.h> | ||
17 | 19 | ||
18 | #include "cbe_regs.h" | 20 | #include "cbe_regs.h" |
19 | 21 | ||
@@ -27,6 +29,7 @@ | |||
27 | static struct cbe_regs_map | 29 | static struct cbe_regs_map |
28 | { | 30 | { |
29 | struct device_node *cpu_node; | 31 | struct device_node *cpu_node; |
32 | struct device_node *be_node; | ||
30 | struct cbe_pmd_regs __iomem *pmd_regs; | 33 | struct cbe_pmd_regs __iomem *pmd_regs; |
31 | struct cbe_iic_regs __iomem *iic_regs; | 34 | struct cbe_iic_regs __iomem *iic_regs; |
32 | struct cbe_mic_tm_regs __iomem *mic_tm_regs; | 35 | struct cbe_mic_tm_regs __iomem *mic_tm_regs; |
@@ -37,6 +40,7 @@ static int cbe_regs_map_count; | |||
37 | static struct cbe_thread_map | 40 | static struct cbe_thread_map |
38 | { | 41 | { |
39 | struct device_node *cpu_node; | 42 | struct device_node *cpu_node; |
43 | struct device_node *be_node; | ||
40 | struct cbe_regs_map *regs; | 44 | struct cbe_regs_map *regs; |
41 | unsigned int thread_id; | 45 | unsigned int thread_id; |
42 | unsigned int cbe_id; | 46 | unsigned int cbe_id; |
@@ -50,22 +54,29 @@ static struct cbe_regs_map *cbe_find_map(struct device_node *np) | |||
50 | int i; | 54 | int i; |
51 | struct device_node *tmp_np; | 55 | struct device_node *tmp_np; |
52 | 56 | ||
53 | if (strcasecmp(np->type, "spe") == 0) { | 57 | if (strcasecmp(np->type, "spe")) { |
54 | if (np->data == NULL) { | 58 | for (i = 0; i < cbe_regs_map_count; i++) |
55 | /* walk up path until cpu node was found */ | 59 | if (cbe_regs_maps[i].cpu_node == np || |
56 | tmp_np = np->parent; | 60 | cbe_regs_maps[i].be_node == np) |
57 | while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0) | 61 | return &cbe_regs_maps[i]; |
58 | tmp_np = tmp_np->parent; | 62 | return NULL; |
63 | } | ||
59 | 64 | ||
60 | np->data = cbe_find_map(tmp_np); | 65 | if (np->data) |
61 | } | ||
62 | return np->data; | 66 | return np->data; |
63 | } | ||
64 | 67 | ||
65 | for (i = 0; i < cbe_regs_map_count; i++) | 68 | /* walk up path until cpu or be node was found */ |
66 | if (cbe_regs_maps[i].cpu_node == np) | 69 | tmp_np = np; |
67 | return &cbe_regs_maps[i]; | 70 | do { |
68 | return NULL; | 71 | tmp_np = tmp_np->parent; |
72 | /* on a correct devicetree we wont get up to root */ | ||
73 | BUG_ON(!tmp_np); | ||
74 | } while (strcasecmp(tmp_np->type, "cpu") && | ||
75 | strcasecmp(tmp_np->type, "be")); | ||
76 | |||
77 | np->data = cbe_find_map(tmp_np); | ||
78 | |||
79 | return np->data; | ||
69 | } | 80 | } |
70 | 81 | ||
71 | struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) | 82 | struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) |
@@ -153,6 +164,67 @@ u32 cbe_node_to_cpu(int node) | |||
153 | } | 164 | } |
154 | EXPORT_SYMBOL_GPL(cbe_node_to_cpu); | 165 | EXPORT_SYMBOL_GPL(cbe_node_to_cpu); |
155 | 166 | ||
167 | static struct device_node *cbe_get_be_node(int cpu_id) | ||
168 | { | ||
169 | struct device_node *np; | ||
170 | |||
171 | for_each_node_by_type (np, "be") { | ||
172 | int len,i; | ||
173 | const phandle *cpu_handle; | ||
174 | |||
175 | cpu_handle = of_get_property(np, "cpus", &len); | ||
176 | |||
177 | for (i=0; i<len; i++) | ||
178 | if (of_find_node_by_phandle(cpu_handle[i]) == of_get_cpu_node(cpu_id, NULL)) | ||
179 | return np; | ||
180 | } | ||
181 | |||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | void __init cbe_fill_regs_map(struct cbe_regs_map *map) | ||
186 | { | ||
187 | if(map->be_node) { | ||
188 | struct device_node *be, *np; | ||
189 | |||
190 | be = map->be_node; | ||
191 | |||
192 | for_each_node_by_type(np, "pervasive") | ||
193 | if (of_get_parent(np) == be) | ||
194 | map->pmd_regs = of_iomap(np, 0); | ||
195 | |||
196 | for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller") | ||
197 | if (of_get_parent(np) == be) | ||
198 | map->iic_regs = of_iomap(np, 2); | ||
199 | |||
200 | for_each_node_by_type(np, "mic-tm") | ||
201 | if (of_get_parent(np) == be) | ||
202 | map->mic_tm_regs = of_iomap(np, 0); | ||
203 | } else { | ||
204 | struct device_node *cpu; | ||
205 | /* That hack must die die die ! */ | ||
206 | const struct address_prop { | ||
207 | unsigned long address; | ||
208 | unsigned int len; | ||
209 | } __attribute__((packed)) *prop; | ||
210 | |||
211 | cpu = map->cpu_node; | ||
212 | |||
213 | prop = of_get_property(cpu, "pervasive", NULL); | ||
214 | if (prop != NULL) | ||
215 | map->pmd_regs = ioremap(prop->address, prop->len); | ||
216 | |||
217 | prop = of_get_property(cpu, "iic", NULL); | ||
218 | if (prop != NULL) | ||
219 | map->iic_regs = ioremap(prop->address, prop->len); | ||
220 | |||
221 | prop = of_get_property(cpu, "mic-tm", NULL); | ||
222 | if (prop != NULL) | ||
223 | map->mic_tm_regs = ioremap(prop->address, prop->len); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | |||
156 | void __init cbe_regs_init(void) | 228 | void __init cbe_regs_init(void) |
157 | { | 229 | { |
158 | int i; | 230 | int i; |
@@ -162,6 +234,7 @@ void __init cbe_regs_init(void) | |||
162 | /* Build local fast map of CPUs */ | 234 | /* Build local fast map of CPUs */ |
163 | for_each_possible_cpu(i) { | 235 | for_each_possible_cpu(i) { |
164 | cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id); | 236 | cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id); |
237 | cbe_thread_map[i].be_node = cbe_get_be_node(i); | ||
165 | cbe_thread_map[i].thread_id = thread_id; | 238 | cbe_thread_map[i].thread_id = thread_id; |
166 | } | 239 | } |
167 | 240 | ||
@@ -170,12 +243,6 @@ void __init cbe_regs_init(void) | |||
170 | struct cbe_regs_map *map; | 243 | struct cbe_regs_map *map; |
171 | unsigned int cbe_id; | 244 | unsigned int cbe_id; |
172 | 245 | ||
173 | /* That hack must die die die ! */ | ||
174 | const struct address_prop { | ||
175 | unsigned long address; | ||
176 | unsigned int len; | ||
177 | } __attribute__((packed)) *prop; | ||
178 | |||
179 | cbe_id = cbe_regs_map_count++; | 246 | cbe_id = cbe_regs_map_count++; |
180 | map = &cbe_regs_maps[cbe_id]; | 247 | map = &cbe_regs_maps[cbe_id]; |
181 | 248 | ||
@@ -193,23 +260,14 @@ void __init cbe_regs_init(void) | |||
193 | if (thread->cpu_node == cpu) { | 260 | if (thread->cpu_node == cpu) { |
194 | thread->regs = map; | 261 | thread->regs = map; |
195 | thread->cbe_id = cbe_id; | 262 | thread->cbe_id = cbe_id; |
263 | map->be_node = thread->be_node; | ||
196 | cpu_set(i, cbe_local_mask[cbe_id]); | 264 | cpu_set(i, cbe_local_mask[cbe_id]); |
197 | if(thread->thread_id == 0) | 265 | if(thread->thread_id == 0) |
198 | cpu_set(i, cbe_first_online_cpu); | 266 | cpu_set(i, cbe_first_online_cpu); |
199 | } | 267 | } |
200 | } | 268 | } |
201 | 269 | ||
202 | prop = of_get_property(cpu, "pervasive", NULL); | 270 | cbe_fill_regs_map(map); |
203 | if (prop != NULL) | ||
204 | map->pmd_regs = ioremap(prop->address, prop->len); | ||
205 | |||
206 | prop = of_get_property(cpu, "iic", NULL); | ||
207 | if (prop != NULL) | ||
208 | map->iic_regs = ioremap(prop->address, prop->len); | ||
209 | |||
210 | prop = of_get_property(cpu, "mic-tm", NULL); | ||
211 | if (prop != NULL) | ||
212 | map->mic_tm_regs = ioremap(prop->address, prop->len); | ||
213 | } | 271 | } |
214 | } | 272 | } |
215 | 273 | ||