X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fplatforms%2Fcell%2Fsetup.c;h=b33a4443f5a9368344f6ac3f3507ac6593a86e77;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=fd3e5609e3e004492fdbded682e899f4da21eec8;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index fd3e5609e..b33a4443f 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include @@ -48,7 +46,6 @@ #include #include #include -#include #include "interrupt.h" #include "iommu.h" @@ -72,6 +69,77 @@ static void cell_show_cpuinfo(struct seq_file *m) of_node_put(root); } +#ifdef CONFIG_SPARSEMEM +static int __init find_spu_node_id(struct device_node *spe) +{ + unsigned int *id; +#ifdef CONFIG_NUMA + struct device_node *cpu; + cpu = spe->parent->parent; + id = (unsigned int *)get_property(cpu, "node-id", NULL); +#else + id = NULL; +#endif + return id ? *id : 0; +} + +static void __init cell_spuprop_present(struct device_node *spe, + const char *prop, int early) +{ + struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *p; + int proplen; + + unsigned long start_pfn, end_pfn, pfn; + int node_id; + + p = (void*)get_property(spe, prop, &proplen); + WARN_ON(proplen != sizeof (*p)); + + node_id = find_spu_node_id(spe); + + start_pfn = p->address >> PAGE_SHIFT; + end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; + + /* We need to call memory_present *before* the call to sparse_init, + but we can initialize the page structs only *after* that call. + Thus, we're being called twice. */ + if (early) + memory_present(node_id, start_pfn, end_pfn); + else { + /* As the pages backing SPU LS and I/O are outside the range + of regular memory, their page structs were not initialized + by free_area_init. Do it here instead. */ + for (pfn = start_pfn; pfn < end_pfn; pfn++) { + struct page *page = pfn_to_page(pfn); + set_page_links(page, ZONE_DMA, node_id, pfn); + set_page_count(page, 1); + reset_page_mapcount(page); + SetPageReserved(page); + INIT_LIST_HEAD(&page->lru); + } + } +} + +static void __init cell_spumem_init(int early) +{ + struct device_node *node; + for (node = of_find_node_by_type(NULL, "spe"); + node; node = of_find_node_by_type(node, "spe")) { + cell_spuprop_present(node, "local-store", early); + cell_spuprop_present(node, "problem", early); + cell_spuprop_present(node, "priv1", early); + cell_spuprop_present(node, "priv2", early); + } +} +#else +static void __init cell_spumem_init(int early) +{ +} +#endif + static void cell_progress(char *s, unsigned short hex) { printk("*** %04x : %s\n", hex, s ? s : ""); @@ -104,6 +172,8 @@ static void __init cell_setup_arch(void) #endif mmio_nvram_init(); + + cell_spumem_init(0); } /* @@ -119,19 +189,18 @@ static void __init cell_init_early(void) ppc64_interrupt_controller = IC_CELL_PIC; + cell_spumem_init(1); + DBG(" <- cell_init_early()\n"); } -static int __init cell_probe(void) +static int __init cell_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "IBM,CBEA") || - of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 1; + if (platform != PLATFORM_CELL) + return 0; - return 0; + return 1; } /* @@ -143,8 +212,7 @@ static int cell_check_legacy_ioport(unsigned int baseport) return -ENODEV; } -define_machine(cell) { - .name = "Cell", +struct machdep_calls __initdata cell_md = { .probe = cell_probe, .setup_arch = cell_setup_arch, .init_early = cell_init_early,