aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spu_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index ef47a6239d4..b788e165c55 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -520,6 +520,56 @@ void spu_irq_setaffinity(struct spu *spu, int cpu)
520} 520}
521EXPORT_SYMBOL_GPL(spu_irq_setaffinity); 521EXPORT_SYMBOL_GPL(spu_irq_setaffinity);
522 522
523static int __init find_spu_node_id(struct device_node *spe)
524{
525 unsigned int *id;
526 struct device_node *cpu;
527 cpu = spe->parent->parent;
528 id = (unsigned int *)get_property(cpu, "node-id", NULL);
529 return id ? *id : 0;
530}
531
532static int __init cell_spuprop_present(struct device_node *spe,
533 const char *prop)
534{
535 static DEFINE_MUTEX(add_spumem_mutex);
536
537 struct address_prop {
538 unsigned long address;
539 unsigned int len;
540 } __attribute__((packed)) *p;
541 int proplen;
542
543 unsigned long start_pfn, nr_pages;
544 int node_id;
545 struct pglist_data *pgdata;
546 struct zone *zone;
547 int ret;
548
549 p = (void*)get_property(spe, prop, &proplen);
550 WARN_ON(proplen != sizeof (*p));
551
552 start_pfn = p->address >> PAGE_SHIFT;
553 nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
554
555 /*
556 * XXX need to get the correct NUMA node in here. This may
557 * be different from the spe::node_id property, e.g. when
558 * the host firmware is not NUMA aware.
559 */
560 node_id = 0;
561
562 pgdata = NODE_DATA(node_id);
563 zone = pgdata->node_zones;
564
565 /* XXX rethink locking here */
566 mutex_lock(&add_spumem_mutex);
567 ret = __add_pages(zone, start_pfn, nr_pages);
568 mutex_unlock(&add_spumem_mutex);
569
570 return ret;
571}
572
523static void __iomem * __init map_spe_prop(struct device_node *n, 573static void __iomem * __init map_spe_prop(struct device_node *n,
524 const char *name) 574 const char *name)
525{ 575{
@@ -530,6 +580,8 @@ static void __iomem * __init map_spe_prop(struct device_node *n,
530 580
531 void *p; 581 void *p;
532 int proplen; 582 int proplen;
583 void* ret = NULL;
584 int err = 0;
533 585
534 p = get_property(n, name, &proplen); 586 p = get_property(n, name, &proplen);
535 if (proplen != sizeof (struct address_prop)) 587 if (proplen != sizeof (struct address_prop))
@@ -537,7 +589,14 @@ static void __iomem * __init map_spe_prop(struct device_node *n,
537 589
538 prop = p; 590 prop = p;
539 591
540 return ioremap(prop->address, prop->len); 592 err = cell_spuprop_present(n, name);
593 if (err && (err != -EEXIST))
594 goto out;
595
596 ret = ioremap(prop->address, prop->len);
597
598 out:
599 return ret;
541} 600}
542 601
543static void spu_unmap(struct spu *spu) 602static void spu_unmap(struct spu *spu)
@@ -597,17 +656,6 @@ out:
597 return ret; 656 return ret;
598} 657}
599 658
600static int __init find_spu_node_id(struct device_node *spe)
601{
602 unsigned int *id;
603 struct device_node *cpu;
604
605 cpu = spe->parent->parent;
606 id = (unsigned int *)get_property(cpu, "node-id", NULL);
607
608 return id ? *id : 0;
609}
610
611static int __init create_spu(struct device_node *spe) 659static int __init create_spu(struct device_node *spe)
612{ 660{
613 struct spu *spu; 661 struct spu *spu;