diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 72 |
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 | } |
521 | EXPORT_SYMBOL_GPL(spu_irq_setaffinity); | 521 | EXPORT_SYMBOL_GPL(spu_irq_setaffinity); |
522 | 522 | ||
523 | static 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 | |||
532 | static 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 | |||
523 | static void __iomem * __init map_spe_prop(struct device_node *n, | 573 | static 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 | ||
543 | static void spu_unmap(struct spu *spu) | 602 | static void spu_unmap(struct spu *spu) |
@@ -597,17 +656,6 @@ out: | |||
597 | return ret; | 656 | return ret; |
598 | } | 657 | } |
599 | 658 | ||
600 | static 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 | |||
611 | static int __init create_spu(struct device_node *spe) | 659 | static int __init create_spu(struct device_node *spe) |
612 | { | 660 | { |
613 | struct spu *spu; | 661 | struct spu *spu; |