aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-19 09:32:44 -0500
committerArnd Bergmann <arnd@klappe.arndb.de>2006-12-19 09:35:38 -0500
commit6e22ba63f01b9bdcd1f29251a95047d310526207 (patch)
tree0fdf36a4ea007f1b72157c2e925d08ac9f9dbc13 /arch/powerpc
parenta24e57be9baed6ccb552fbdb8e7e29e9c2da0375 (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.c67
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
40static DEFINE_MUTEX(add_spumem_mutex);
41
40struct spu_pdata { 42struct 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)
68static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, 70static 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
240static int spu_map_resource(struct device_node *node, int nr, 240static 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
256out: 273out:
257 return ret; 274 return ret;
258} 275}
259 276
260static int __init spu_map_device(struct spu *spu, struct device_node *node) 277static 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);