Merge branch 'clockevents/fixes' of git://git.linaro.org/people/daniel.lezcano/linux...
[linux-drm-fsl-dcu.git] / arch / powerpc / platforms / wsp / wsp.c
1 /*
2  * Copyright 2008-2011, IBM Corporation
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version
7  * 2 of the License, or (at your option) any later version.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/smp.h>
14 #include <linux/delay.h>
15 #include <linux/time.h>
16 #include <linux/of_address.h>
17
18 #include <asm/scom.h>
19
20 #include "wsp.h"
21 #include "ics.h"
22
23 #define WSP_SOC_COMPATIBLE      "ibm,wsp-soc"
24 #define PBIC_COMPATIBLE         "ibm,wsp-pbic"
25 #define COPRO_COMPATIBLE        "ibm,wsp-coprocessor"
26
27 static int __init wsp_probe_buses(void)
28 {
29         static __initdata struct of_device_id bus_ids[] = {
30                 /*
31                  * every node in between needs to be here or you won't
32                  * find it
33                  */
34                 { .compatible = WSP_SOC_COMPATIBLE, },
35                 { .compatible = PBIC_COMPATIBLE, },
36                 { .compatible = COPRO_COMPATIBLE, },
37                 {},
38         };
39         of_platform_bus_probe(NULL, bus_ids, NULL);
40
41         return 0;
42 }
43
44 void __init wsp_setup_arch(void)
45 {
46         /* init to some ~sane value until calibrate_delay() runs */
47         loops_per_jiffy = 50000000;
48
49         scom_init_wsp();
50
51         /* Setup SMP callback */
52 #ifdef CONFIG_SMP
53         a2_setup_smp();
54 #endif
55 #ifdef CONFIG_PCI
56         wsp_setup_pci();
57 #endif
58 }
59
60 void __init wsp_setup_irq(void)
61 {
62         wsp_init_irq();
63         opb_pic_init();
64 }
65
66
67 int __init wsp_probe_devices(void)
68 {
69         struct device_node *np;
70
71         /* Our RTC is a ds1500. It seems to be programatically compatible
72          * with the ds1511 for which we have a driver so let's use that
73          */
74         np = of_find_compatible_node(NULL, NULL, "dallas,ds1500");
75         if (np != NULL) {
76                 struct resource res;
77                 if (of_address_to_resource(np, 0, &res) == 0)
78                         platform_device_register_simple("ds1511", 0, &res, 1);
79         }
80
81         wsp_probe_buses();
82
83         return 0;
84 }
85
86 void wsp_halt(void)
87 {
88         u64 val;
89         scom_map_t m;
90         struct device_node *dn;
91         struct device_node *mine;
92         struct device_node *me;
93         int rc;
94
95         me = of_get_cpu_node(smp_processor_id(), NULL);
96         mine = scom_find_parent(me);
97
98         /* This will halt all the A2s but not power off the chip */
99         for_each_node_with_property(dn, "scom-controller") {
100                 if (dn == mine)
101                         continue;
102                 m = scom_map(dn, 0, 1);
103
104                 /* read-modify-write it so the HW probe does not get
105                  * confused */
106                 rc = scom_read(m, 0, &val);
107                 if (rc == 0)
108                         scom_write(m, 0, val | 1);
109                 scom_unmap(m);
110         }
111         m = scom_map(mine, 0, 1);
112         rc = scom_read(m, 0, &val);
113         if (rc == 0)
114                 scom_write(m, 0, val | 1);
115         /* should never return */
116         scom_unmap(m);
117 }