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 @@ | |||
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 | |||
17 | #include <asm/scom.h> | ||
18 | |||
19 | #include "wsp.h" | ||
20 | #include "ics.h" | ||
21 | |||
22 | #define WSP_SOC_COMPATIBLE "ibm,wsp-soc" | ||
23 | #define PBIC_COMPATIBLE "ibm,wsp-pbic" | ||
24 | #define COPRO_COMPATIBLE "ibm,wsp-coprocessor" | ||
25 | |||
26 | static int __init wsp_probe_buses(void) | ||
27 | { | ||
28 | static __initdata struct of_device_id bus_ids[] = { | ||
29 | /* | ||
30 | * every node in between needs to be here or you won't | ||
31 | * find it | ||
32 | */ | ||
33 | { .compatible = WSP_SOC_COMPATIBLE, }, | ||
34 | { .compatible = PBIC_COMPATIBLE, }, | ||
35 | { .compatible = COPRO_COMPATIBLE, }, | ||
36 | {}, | ||
37 | }; | ||
38 | of_platform_bus_probe(NULL, bus_ids, NULL); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | void __init wsp_setup_arch(void) | ||
44 | { | ||
45 | /* init to some ~sane value until calibrate_delay() runs */ | ||
46 | loops_per_jiffy = 50000000; | ||
47 | |||
48 | scom_init_wsp(); | ||
49 | |||
50 | /* Setup SMP callback */ | ||
51 | #ifdef CONFIG_SMP | ||
52 | a2_setup_smp(); | ||
53 | #endif | ||
54 | #ifdef CONFIG_PCI | ||
55 | wsp_setup_pci(); | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | void __init wsp_setup_irq(void) | ||
60 | { | ||
61 | wsp_init_irq(); | ||
62 | opb_pic_init(); | ||
63 | } | ||
64 | |||
65 | |||
66 | int __init wsp_probe_devices(void) | ||
67 | { | ||
68 | struct device_node *np; | ||
69 | |||
70 | /* Our RTC is a ds1500. It seems to be programatically compatible | ||
71 | * with the ds1511 for which we have a driver so let's use that | ||
72 | */ | ||
73 | np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); | ||
74 | if (np != NULL) { | ||
75 | struct resource res; | ||
76 | if (of_address_to_resource(np, 0, &res) == 0) | ||
77 | platform_device_register_simple("ds1511", 0, &res, 1); | ||
78 | } | ||
79 | |||
80 | wsp_probe_buses(); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | void wsp_halt(void) | ||
86 | { | ||
87 | u64 val; | ||
88 | scom_map_t m; | ||
89 | struct device_node *dn; | ||
90 | struct device_node *mine; | ||
91 | struct device_node *me; | ||
92 | |||
93 | me = of_get_cpu_node(smp_processor_id(), NULL); | ||
94 | mine = scom_find_parent(me); | ||
95 | |||
96 | /* This will halt all the A2s but not power off the chip */ | ||
97 | for_each_node_with_property(dn, "scom-controller") { | ||
98 | if (dn == mine) | ||
99 | continue; | ||
100 | m = scom_map(dn, 0, 1); | ||
101 | |||
102 | /* read-modify-write it so the HW probe does not get | ||
103 | * confused */ | ||
104 | val = scom_read(m, 0); | ||
105 | val |= 1; | ||
106 | scom_write(m, 0, val); | ||
107 | scom_unmap(m); | ||
108 | } | ||
109 | m = scom_map(mine, 0, 1); | ||
110 | val = scom_read(m, 0); | ||
111 | val |= 1; | ||
112 | scom_write(m, 0, val); | ||
113 | /* should never return */ | ||
114 | scom_unmap(m); | ||
115 | } | ||