diff options
Diffstat (limited to 'arch/powerpc/platforms/wsp/wsp.c')
-rw-r--r-- | arch/powerpc/platforms/wsp/wsp.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c new file mode 100644 index 000000000000..d25cc96c21b8 --- /dev/null +++ b/arch/powerpc/platforms/wsp/wsp.c @@ -0,0 +1,115 @@ +/* + * Copyright 2008-2011, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/smp.h> +#include <linux/delay.h> +#include <linux/time.h> + +#include <asm/scom.h> + +#include "wsp.h" +#include "ics.h" + +#define WSP_SOC_COMPATIBLE "ibm,wsp-soc" +#define PBIC_COMPATIBLE "ibm,wsp-pbic" +#define COPRO_COMPATIBLE "ibm,wsp-coprocessor" + +static int __init wsp_probe_buses(void) +{ + static __initdata struct of_device_id bus_ids[] = { + /* + * every node in between needs to be here or you won't + * find it + */ + { .compatible = WSP_SOC_COMPATIBLE, }, + { .compatible = PBIC_COMPATIBLE, }, + { .compatible = COPRO_COMPATIBLE, }, + {}, + }; + of_platform_bus_probe(NULL, bus_ids, NULL); + + return 0; +} + +void __init wsp_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000; + + scom_init_wsp(); + + /* Setup SMP callback */ +#ifdef CONFIG_SMP + a2_setup_smp(); +#endif +#ifdef CONFIG_PCI + wsp_setup_pci(); +#endif +} + +void __init wsp_setup_irq(void) +{ + wsp_init_irq(); + opb_pic_init(); +} + + +int __init wsp_probe_devices(void) +{ + struct device_node *np; + + /* Our RTC is a ds1500. It seems to be programatically compatible + * with the ds1511 for which we have a driver so let's use that + */ + np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); + if (np != NULL) { + struct resource res; + if (of_address_to_resource(np, 0, &res) == 0) + platform_device_register_simple("ds1511", 0, &res, 1); + } + + wsp_probe_buses(); + + return 0; +} + +void wsp_halt(void) +{ + u64 val; + scom_map_t m; + struct device_node *dn; + struct device_node *mine; + struct device_node *me; + + me = of_get_cpu_node(smp_processor_id(), NULL); + mine = scom_find_parent(me); + + /* This will halt all the A2s but not power off the chip */ + for_each_node_with_property(dn, "scom-controller") { + if (dn == mine) + continue; + m = scom_map(dn, 0, 1); + + /* read-modify-write it so the HW probe does not get + * confused */ + val = scom_read(m, 0); + val |= 1; + scom_write(m, 0, val); + scom_unmap(m); + } + m = scom_map(mine, 0, 1); + val = scom_read(m, 0); + val |= 1; + scom_write(m, 0, val); + /* should never return */ + scom_unmap(m); +} |