/* * 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); }