diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-12-19 09:32:44 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2006-12-19 09:35:38 -0500 |
commit | 6e22ba63f01b9bdcd1f29251a95047d310526207 (patch) | |
tree | 0fdf36a4ea007f1b72157c2e925d08ac9f9dbc13 /arch/powerpc | |
parent | a24e57be9baed6ccb552fbdb8e7e29e9c2da0375 (diff) |
[POWERPC] cell: Fix spufs with "new style" device-tree
Some SPU code was a bit too convoluted and broke when adding support for
the new style device-tree, most notably the struct pages for SPEs no
longer get created. oops...
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/cell/spu_priv1_mmio.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index a5de0430c56d..c805e63b7d5c 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include "interrupt.h" | 37 | #include "interrupt.h" |
38 | #include "spu_priv1_mmio.h" | 38 | #include "spu_priv1_mmio.h" |
39 | 39 | ||
40 | static DEFINE_MUTEX(add_spumem_mutex); | ||
41 | |||
40 | struct spu_pdata { | 42 | struct spu_pdata { |
41 | int nid; | 43 | int nid; |
42 | struct device_node *devnode; | 44 | struct device_node *devnode; |
@@ -68,8 +70,6 @@ static int __init find_spu_node_id(struct device_node *spe) | |||
68 | static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, | 70 | static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, |
69 | const char *prop) | 71 | const char *prop) |
70 | { | 72 | { |
71 | static DEFINE_MUTEX(add_spumem_mutex); | ||
72 | |||
73 | const struct address_prop { | 73 | const struct address_prop { |
74 | unsigned long address; | 74 | unsigned long address; |
75 | unsigned int len; | 75 | unsigned int len; |
@@ -237,70 +237,88 @@ err: | |||
237 | return ret; | 237 | return ret; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int spu_map_resource(struct device_node *node, int nr, | 240 | static int spu_map_resource(struct spu *spu, int nr, |
241 | void __iomem** virt, unsigned long *phys) | 241 | void __iomem** virt, unsigned long *phys) |
242 | { | 242 | { |
243 | struct device_node *np = spu_get_pdata(spu)->devnode; | ||
244 | unsigned long start_pfn, nr_pages; | ||
245 | struct pglist_data *pgdata; | ||
246 | struct zone *zone; | ||
243 | struct resource resource = { }; | 247 | struct resource resource = { }; |
248 | unsigned long len; | ||
244 | int ret; | 249 | int ret; |
245 | 250 | ||
246 | ret = of_address_to_resource(node, nr, &resource); | 251 | ret = of_address_to_resource(np, nr, &resource); |
247 | if (ret) | 252 | if (ret) |
248 | goto out; | 253 | goto out; |
249 | 254 | ||
250 | if (phys) | 255 | if (phys) |
251 | *phys = resource.start; | 256 | *phys = resource.start; |
252 | *virt = ioremap(resource.start, resource.end - resource.start); | 257 | len = resource.end - resource.start + 1; |
258 | *virt = ioremap(resource.start, len); | ||
253 | if (!*virt) | 259 | if (!*virt) |
254 | ret = -EINVAL; | 260 | ret = -EINVAL; |
255 | 261 | ||
262 | start_pfn = resource.start >> PAGE_SHIFT; | ||
263 | nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
264 | |||
265 | pgdata = NODE_DATA(spu_get_pdata(spu)->nid); | ||
266 | zone = pgdata->node_zones; | ||
267 | |||
268 | /* XXX rethink locking here */ | ||
269 | mutex_lock(&add_spumem_mutex); | ||
270 | ret = __add_pages(zone, start_pfn, nr_pages); | ||
271 | mutex_unlock(&add_spumem_mutex); | ||
272 | |||
256 | out: | 273 | out: |
257 | return ret; | 274 | return ret; |
258 | } | 275 | } |
259 | 276 | ||
260 | static int __init spu_map_device(struct spu *spu, struct device_node *node) | 277 | static int __init spu_map_device(struct spu *spu) |
261 | { | 278 | { |
279 | struct device_node *np = spu_get_pdata(spu)->devnode; | ||
262 | int ret = -ENODEV; | 280 | int ret = -ENODEV; |
263 | spu->name = get_property(node, "name", NULL); | 281 | |
282 | spu->name = get_property(np, "name", NULL); | ||
264 | if (!spu->name) | 283 | if (!spu->name) |
265 | goto out; | 284 | goto out; |
266 | 285 | ||
267 | ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, | 286 | ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, |
268 | &spu->local_store_phys); | 287 | &spu->local_store_phys); |
269 | if (ret) { | 288 | if (ret) { |
270 | pr_debug("spu_new: failed to map %s resource 0\n", | 289 | pr_debug("spu_new: failed to map %s resource 0\n", |
271 | node->full_name); | 290 | np->full_name); |
272 | goto out; | 291 | goto out; |
273 | } | 292 | } |
274 | ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, | 293 | ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, |
275 | &spu->problem_phys); | 294 | &spu->problem_phys); |
276 | if (ret) { | 295 | if (ret) { |
277 | pr_debug("spu_new: failed to map %s resource 1\n", | 296 | pr_debug("spu_new: failed to map %s resource 1\n", |
278 | node->full_name); | 297 | np->full_name); |
279 | goto out_unmap; | 298 | goto out_unmap; |
280 | } | 299 | } |
281 | ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, | 300 | ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); |
282 | NULL); | ||
283 | if (ret) { | 301 | if (ret) { |
284 | pr_debug("spu_new: failed to map %s resource 2\n", | 302 | pr_debug("spu_new: failed to map %s resource 2\n", |
285 | node->full_name); | 303 | np->full_name); |
286 | goto out_unmap; | 304 | goto out_unmap; |
287 | } | 305 | } |
288 | if (!firmware_has_feature(FW_FEATURE_LPAR)) | 306 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
289 | ret = spu_map_resource(node, 3, | 307 | ret = spu_map_resource(spu, 3, |
290 | (void __iomem**)&spu_get_pdata(spu)->priv1, NULL); | 308 | (void __iomem**)&spu_get_pdata(spu)->priv1, NULL); |
291 | if (ret) { | 309 | if (ret) { |
292 | pr_debug("spu_new: failed to map %s resource 3\n", | 310 | pr_debug("spu_new: failed to map %s resource 3\n", |
293 | node->full_name); | 311 | np->full_name); |
294 | goto out_unmap; | 312 | goto out_unmap; |
295 | } | 313 | } |
296 | pr_debug("spu_new: %s maps:\n", node->full_name); | 314 | pr_debug("spu_new: %s maps:\n", np->full_name); |
297 | pr_debug(" local store : 0x%016lx -> 0x%p\n", | 315 | pr_debug(" local store : 0x%016lx -> 0x%p\n", |
298 | spu->local_store_phys, spu->local_store); | 316 | spu->local_store_phys, spu->local_store); |
299 | pr_debug(" problem state : 0x%016lx -> 0x%p\n", | 317 | pr_debug(" problem state : 0x%016lx -> 0x%p\n", |
300 | spu->problem_phys, spu->problem); | 318 | spu->problem_phys, spu->problem); |
301 | pr_debug(" priv2 : 0x%p\n", spu->priv2); | 319 | pr_debug(" priv2 : 0x%p\n", spu->priv2); |
302 | pr_debug(" priv1 : 0x%p\n", | 320 | pr_debug(" priv1 : 0x%p\n", |
303 | spu_get_pdata(spu)->priv1); | 321 | spu_get_pdata(spu)->priv1); |
304 | 322 | ||
305 | return 0; | 323 | return 0; |
306 | 324 | ||
@@ -340,6 +358,7 @@ static int __init of_create_spu(struct spu *spu, void *data) | |||
340 | ret = -ENOMEM; | 358 | ret = -ENOMEM; |
341 | goto out; | 359 | goto out; |
342 | } | 360 | } |
361 | spu_get_pdata(spu)->devnode = of_node_get(spe); | ||
343 | 362 | ||
344 | spu->node = find_spu_node_id(spe); | 363 | spu->node = find_spu_node_id(spe); |
345 | if (spu->node >= MAX_NUMNODES) { | 364 | if (spu->node >= MAX_NUMNODES) { |
@@ -354,7 +373,7 @@ static int __init of_create_spu(struct spu *spu, void *data) | |||
354 | if (spu_get_pdata(spu)->nid == -1) | 373 | if (spu_get_pdata(spu)->nid == -1) |
355 | spu_get_pdata(spu)->nid = 0; | 374 | spu_get_pdata(spu)->nid = 0; |
356 | 375 | ||
357 | ret = spu_map_device(spu, spe); | 376 | ret = spu_map_device(spu); |
358 | /* try old method */ | 377 | /* try old method */ |
359 | if (ret) | 378 | if (ret) |
360 | ret = spu_map_device_old(spu, spe); | 379 | ret = spu_map_device_old(spu, spe); |
@@ -367,8 +386,6 @@ static int __init of_create_spu(struct spu *spu, void *data) | |||
367 | if (ret) | 386 | if (ret) |
368 | goto out_unmap; | 387 | goto out_unmap; |
369 | 388 | ||
370 | spu_get_pdata(spu)->devnode = of_node_get(spe); | ||
371 | |||
372 | pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name, | 389 | pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name, |
373 | spu->local_store, spu->problem, spu_get_pdata(spu)->priv1, | 390 | spu->local_store, spu->problem, spu_get_pdata(spu)->priv1, |
374 | spu->priv2, spu->number); | 391 | spu->priv2, spu->number); |