Commit | Line | Data |
---|---|---|
cc35b676 JX |
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> | |
dc7a9bd3 | 16 | #include <linux/of_address.h> |
cc35b676 JX |
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; | |
aaa63093 | 93 | int rc; |
cc35b676 JX |
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 */ | |
aaa63093 BH |
106 | rc = scom_read(m, 0, &val); |
107 | if (rc == 0) | |
108 | scom_write(m, 0, val | 1); | |
cc35b676 JX |
109 | scom_unmap(m); |
110 | } | |
111 | m = scom_map(mine, 0, 1); | |
aaa63093 BH |
112 | rc = scom_read(m, 0, &val); |
113 | if (rc == 0) | |
114 | scom_write(m, 0, val | 1); | |
cc35b676 JX |
115 | /* should never return */ |
116 | scom_unmap(m); | |
117 | } |