Commit 6f3d5d3cc4b1447578ae8484166bbc34a64150c5
Committed by
Paul Mackerras
1 parent
a0a428e300
Exists in
master
and in
7 other branches
[POWERPC] Add a helper for calculating RTAS "config_addr" parameters
Several RTAS calls take a "config_addr" parameter, which is a particular way of specifying a PCI busno, devfn and register number into a 32-bit word. Currently these are open-coded, and I'll be adding another soon, replace them with a helper that encapsulates the logic. Be more strict about masking the busno too, just in case. Booted on P5 LPAR. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 2 changed files with 18 additions and 4 deletions Inline Diff
arch/powerpc/kernel/rtas_pci.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Dave Engebretsen, IBM Corporation | 2 | * Copyright (C) 2001 Dave Engebretsen, IBM Corporation |
3 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | 3 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM |
4 | * | 4 | * |
5 | * RTAS specific routines for PCI. | 5 | * RTAS specific routines for PCI. |
6 | * | 6 | * |
7 | * Based on code from pci.c, chrp_pci.c and pSeries_pci.c | 7 | * Based on code from pci.c, chrp_pci.c and pSeries_pci.c |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/threads.h> | 25 | #include <linux/threads.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/bootmem.h> | 29 | #include <linux/bootmem.h> |
30 | 30 | ||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/machdep.h> | 35 | #include <asm/machdep.h> |
36 | #include <asm/pci-bridge.h> | 36 | #include <asm/pci-bridge.h> |
37 | #include <asm/iommu.h> | 37 | #include <asm/iommu.h> |
38 | #include <asm/rtas.h> | 38 | #include <asm/rtas.h> |
39 | #include <asm/mpic.h> | 39 | #include <asm/mpic.h> |
40 | #include <asm/ppc-pci.h> | 40 | #include <asm/ppc-pci.h> |
41 | 41 | ||
42 | /* RTAS tokens */ | 42 | /* RTAS tokens */ |
43 | static int read_pci_config; | 43 | static int read_pci_config; |
44 | static int write_pci_config; | 44 | static int write_pci_config; |
45 | static int ibm_read_pci_config; | 45 | static int ibm_read_pci_config; |
46 | static int ibm_write_pci_config; | 46 | static int ibm_write_pci_config; |
47 | 47 | ||
48 | static inline int config_access_valid(struct pci_dn *dn, int where) | 48 | static inline int config_access_valid(struct pci_dn *dn, int where) |
49 | { | 49 | { |
50 | if (where < 256) | 50 | if (where < 256) |
51 | return 1; | 51 | return 1; |
52 | if (where < 4096 && dn->pci_ext_config_space) | 52 | if (where < 4096 && dn->pci_ext_config_space) |
53 | return 1; | 53 | return 1; |
54 | 54 | ||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | static int of_device_available(struct device_node * dn) | 58 | static int of_device_available(struct device_node * dn) |
59 | { | 59 | { |
60 | const char *status; | 60 | const char *status; |
61 | 61 | ||
62 | status = get_property(dn, "status", NULL); | 62 | status = get_property(dn, "status", NULL); |
63 | 63 | ||
64 | if (!status) | 64 | if (!status) |
65 | return 1; | 65 | return 1; |
66 | 66 | ||
67 | if (!strcmp(status, "okay")) | 67 | if (!strcmp(status, "okay")) |
68 | return 1; | 68 | return 1; |
69 | 69 | ||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) | 73 | int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) |
74 | { | 74 | { |
75 | int returnval = -1; | 75 | int returnval = -1; |
76 | unsigned long buid, addr; | 76 | unsigned long buid, addr; |
77 | int ret; | 77 | int ret; |
78 | 78 | ||
79 | if (!pdn) | 79 | if (!pdn) |
80 | return PCIBIOS_DEVICE_NOT_FOUND; | 80 | return PCIBIOS_DEVICE_NOT_FOUND; |
81 | if (!config_access_valid(pdn, where)) | 81 | if (!config_access_valid(pdn, where)) |
82 | return PCIBIOS_BAD_REGISTER_NUMBER; | 82 | return PCIBIOS_BAD_REGISTER_NUMBER; |
83 | 83 | ||
84 | addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | | 84 | addr = rtas_config_addr(pdn->busno, pdn->devfn, where); |
85 | (pdn->devfn << 8) | (where & 0xff); | ||
86 | buid = pdn->phb->buid; | 85 | buid = pdn->phb->buid; |
87 | if (buid) { | 86 | if (buid) { |
88 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, | 87 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, |
89 | addr, BUID_HI(buid), BUID_LO(buid), size); | 88 | addr, BUID_HI(buid), BUID_LO(buid), size); |
90 | } else { | 89 | } else { |
91 | ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); | 90 | ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); |
92 | } | 91 | } |
93 | *val = returnval; | 92 | *val = returnval; |
94 | 93 | ||
95 | if (ret) | 94 | if (ret) |
96 | return PCIBIOS_DEVICE_NOT_FOUND; | 95 | return PCIBIOS_DEVICE_NOT_FOUND; |
97 | 96 | ||
98 | if (returnval == EEH_IO_ERROR_VALUE(size) && | 97 | if (returnval == EEH_IO_ERROR_VALUE(size) && |
99 | eeh_dn_check_failure (pdn->node, NULL)) | 98 | eeh_dn_check_failure (pdn->node, NULL)) |
100 | return PCIBIOS_DEVICE_NOT_FOUND; | 99 | return PCIBIOS_DEVICE_NOT_FOUND; |
101 | 100 | ||
102 | return PCIBIOS_SUCCESSFUL; | 101 | return PCIBIOS_SUCCESSFUL; |
103 | } | 102 | } |
104 | 103 | ||
105 | static int rtas_pci_read_config(struct pci_bus *bus, | 104 | static int rtas_pci_read_config(struct pci_bus *bus, |
106 | unsigned int devfn, | 105 | unsigned int devfn, |
107 | int where, int size, u32 *val) | 106 | int where, int size, u32 *val) |
108 | { | 107 | { |
109 | struct device_node *busdn, *dn; | 108 | struct device_node *busdn, *dn; |
110 | 109 | ||
111 | if (bus->self) | 110 | if (bus->self) |
112 | busdn = pci_device_to_OF_node(bus->self); | 111 | busdn = pci_device_to_OF_node(bus->self); |
113 | else | 112 | else |
114 | busdn = bus->sysdata; /* must be a phb */ | 113 | busdn = bus->sysdata; /* must be a phb */ |
115 | 114 | ||
116 | /* Search only direct children of the bus */ | 115 | /* Search only direct children of the bus */ |
117 | for (dn = busdn->child; dn; dn = dn->sibling) { | 116 | for (dn = busdn->child; dn; dn = dn->sibling) { |
118 | struct pci_dn *pdn = PCI_DN(dn); | 117 | struct pci_dn *pdn = PCI_DN(dn); |
119 | if (pdn && pdn->devfn == devfn | 118 | if (pdn && pdn->devfn == devfn |
120 | && of_device_available(dn)) | 119 | && of_device_available(dn)) |
121 | return rtas_read_config(pdn, where, size, val); | 120 | return rtas_read_config(pdn, where, size, val); |
122 | } | 121 | } |
123 | 122 | ||
124 | return PCIBIOS_DEVICE_NOT_FOUND; | 123 | return PCIBIOS_DEVICE_NOT_FOUND; |
125 | } | 124 | } |
126 | 125 | ||
127 | int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) | 126 | int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) |
128 | { | 127 | { |
129 | unsigned long buid, addr; | 128 | unsigned long buid, addr; |
130 | int ret; | 129 | int ret; |
131 | 130 | ||
132 | if (!pdn) | 131 | if (!pdn) |
133 | return PCIBIOS_DEVICE_NOT_FOUND; | 132 | return PCIBIOS_DEVICE_NOT_FOUND; |
134 | if (!config_access_valid(pdn, where)) | 133 | if (!config_access_valid(pdn, where)) |
135 | return PCIBIOS_BAD_REGISTER_NUMBER; | 134 | return PCIBIOS_BAD_REGISTER_NUMBER; |
136 | 135 | ||
137 | addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | | 136 | addr = rtas_config_addr(pdn->busno, pdn->devfn, where); |
138 | (pdn->devfn << 8) | (where & 0xff); | ||
139 | buid = pdn->phb->buid; | 137 | buid = pdn->phb->buid; |
140 | if (buid) { | 138 | if (buid) { |
141 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, | 139 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, |
142 | BUID_HI(buid), BUID_LO(buid), size, (ulong) val); | 140 | BUID_HI(buid), BUID_LO(buid), size, (ulong) val); |
143 | } else { | 141 | } else { |
144 | ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); | 142 | ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); |
145 | } | 143 | } |
146 | 144 | ||
147 | if (ret) | 145 | if (ret) |
148 | return PCIBIOS_DEVICE_NOT_FOUND; | 146 | return PCIBIOS_DEVICE_NOT_FOUND; |
149 | 147 | ||
150 | return PCIBIOS_SUCCESSFUL; | 148 | return PCIBIOS_SUCCESSFUL; |
151 | } | 149 | } |
152 | 150 | ||
153 | static int rtas_pci_write_config(struct pci_bus *bus, | 151 | static int rtas_pci_write_config(struct pci_bus *bus, |
154 | unsigned int devfn, | 152 | unsigned int devfn, |
155 | int where, int size, u32 val) | 153 | int where, int size, u32 val) |
156 | { | 154 | { |
157 | struct device_node *busdn, *dn; | 155 | struct device_node *busdn, *dn; |
158 | 156 | ||
159 | if (bus->self) | 157 | if (bus->self) |
160 | busdn = pci_device_to_OF_node(bus->self); | 158 | busdn = pci_device_to_OF_node(bus->self); |
161 | else | 159 | else |
162 | busdn = bus->sysdata; /* must be a phb */ | 160 | busdn = bus->sysdata; /* must be a phb */ |
163 | 161 | ||
164 | /* Search only direct children of the bus */ | 162 | /* Search only direct children of the bus */ |
165 | for (dn = busdn->child; dn; dn = dn->sibling) { | 163 | for (dn = busdn->child; dn; dn = dn->sibling) { |
166 | struct pci_dn *pdn = PCI_DN(dn); | 164 | struct pci_dn *pdn = PCI_DN(dn); |
167 | if (pdn && pdn->devfn == devfn | 165 | if (pdn && pdn->devfn == devfn |
168 | && of_device_available(dn)) | 166 | && of_device_available(dn)) |
169 | return rtas_write_config(pdn, where, size, val); | 167 | return rtas_write_config(pdn, where, size, val); |
170 | } | 168 | } |
171 | return PCIBIOS_DEVICE_NOT_FOUND; | 169 | return PCIBIOS_DEVICE_NOT_FOUND; |
172 | } | 170 | } |
173 | 171 | ||
174 | struct pci_ops rtas_pci_ops = { | 172 | struct pci_ops rtas_pci_ops = { |
175 | rtas_pci_read_config, | 173 | rtas_pci_read_config, |
176 | rtas_pci_write_config | 174 | rtas_pci_write_config |
177 | }; | 175 | }; |
178 | 176 | ||
179 | int is_python(struct device_node *dev) | 177 | int is_python(struct device_node *dev) |
180 | { | 178 | { |
181 | const char *model = get_property(dev, "model", NULL); | 179 | const char *model = get_property(dev, "model", NULL); |
182 | 180 | ||
183 | if (model && strstr(model, "Python")) | 181 | if (model && strstr(model, "Python")) |
184 | return 1; | 182 | return 1; |
185 | 183 | ||
186 | return 0; | 184 | return 0; |
187 | } | 185 | } |
188 | 186 | ||
189 | static void python_countermeasures(struct device_node *dev) | 187 | static void python_countermeasures(struct device_node *dev) |
190 | { | 188 | { |
191 | struct resource registers; | 189 | struct resource registers; |
192 | void __iomem *chip_regs; | 190 | void __iomem *chip_regs; |
193 | volatile u32 val; | 191 | volatile u32 val; |
194 | 192 | ||
195 | if (of_address_to_resource(dev, 0, ®isters)) { | 193 | if (of_address_to_resource(dev, 0, ®isters)) { |
196 | printk(KERN_ERR "Can't get address for Python workarounds !\n"); | 194 | printk(KERN_ERR "Can't get address for Python workarounds !\n"); |
197 | return; | 195 | return; |
198 | } | 196 | } |
199 | 197 | ||
200 | /* Python's register file is 1 MB in size. */ | 198 | /* Python's register file is 1 MB in size. */ |
201 | chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000); | 199 | chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000); |
202 | 200 | ||
203 | /* | 201 | /* |
204 | * Firmware doesn't always clear this bit which is critical | 202 | * Firmware doesn't always clear this bit which is critical |
205 | * for good performance - Anton | 203 | * for good performance - Anton |
206 | */ | 204 | */ |
207 | 205 | ||
208 | #define PRG_CL_RESET_VALID 0x00010000 | 206 | #define PRG_CL_RESET_VALID 0x00010000 |
209 | 207 | ||
210 | val = in_be32(chip_regs + 0xf6030); | 208 | val = in_be32(chip_regs + 0xf6030); |
211 | if (val & PRG_CL_RESET_VALID) { | 209 | if (val & PRG_CL_RESET_VALID) { |
212 | printk(KERN_INFO "Python workaround: "); | 210 | printk(KERN_INFO "Python workaround: "); |
213 | val &= ~PRG_CL_RESET_VALID; | 211 | val &= ~PRG_CL_RESET_VALID; |
214 | out_be32(chip_regs + 0xf6030, val); | 212 | out_be32(chip_regs + 0xf6030, val); |
215 | /* | 213 | /* |
216 | * We must read it back for changes to | 214 | * We must read it back for changes to |
217 | * take effect | 215 | * take effect |
218 | */ | 216 | */ |
219 | val = in_be32(chip_regs + 0xf6030); | 217 | val = in_be32(chip_regs + 0xf6030); |
220 | printk("reg0: %x\n", val); | 218 | printk("reg0: %x\n", val); |
221 | } | 219 | } |
222 | 220 | ||
223 | iounmap(chip_regs); | 221 | iounmap(chip_regs); |
224 | } | 222 | } |
225 | 223 | ||
226 | void __init init_pci_config_tokens (void) | 224 | void __init init_pci_config_tokens (void) |
227 | { | 225 | { |
228 | read_pci_config = rtas_token("read-pci-config"); | 226 | read_pci_config = rtas_token("read-pci-config"); |
229 | write_pci_config = rtas_token("write-pci-config"); | 227 | write_pci_config = rtas_token("write-pci-config"); |
230 | ibm_read_pci_config = rtas_token("ibm,read-pci-config"); | 228 | ibm_read_pci_config = rtas_token("ibm,read-pci-config"); |
231 | ibm_write_pci_config = rtas_token("ibm,write-pci-config"); | 229 | ibm_write_pci_config = rtas_token("ibm,write-pci-config"); |
232 | } | 230 | } |
233 | 231 | ||
234 | unsigned long __devinit get_phb_buid (struct device_node *phb) | 232 | unsigned long __devinit get_phb_buid (struct device_node *phb) |
235 | { | 233 | { |
236 | int addr_cells; | 234 | int addr_cells; |
237 | const unsigned int *buid_vals; | 235 | const unsigned int *buid_vals; |
238 | unsigned int len; | 236 | unsigned int len; |
239 | unsigned long buid; | 237 | unsigned long buid; |
240 | 238 | ||
241 | if (ibm_read_pci_config == -1) return 0; | 239 | if (ibm_read_pci_config == -1) return 0; |
242 | 240 | ||
243 | /* PHB's will always be children of the root node, | 241 | /* PHB's will always be children of the root node, |
244 | * or so it is promised by the current firmware. */ | 242 | * or so it is promised by the current firmware. */ |
245 | if (phb->parent == NULL) | 243 | if (phb->parent == NULL) |
246 | return 0; | 244 | return 0; |
247 | if (phb->parent->parent) | 245 | if (phb->parent->parent) |
248 | return 0; | 246 | return 0; |
249 | 247 | ||
250 | buid_vals = get_property(phb, "reg", &len); | 248 | buid_vals = get_property(phb, "reg", &len); |
251 | if (buid_vals == NULL) | 249 | if (buid_vals == NULL) |
252 | return 0; | 250 | return 0; |
253 | 251 | ||
254 | addr_cells = prom_n_addr_cells(phb); | 252 | addr_cells = prom_n_addr_cells(phb); |
255 | if (addr_cells == 1) { | 253 | if (addr_cells == 1) { |
256 | buid = (unsigned long) buid_vals[0]; | 254 | buid = (unsigned long) buid_vals[0]; |
257 | } else { | 255 | } else { |
258 | buid = (((unsigned long)buid_vals[0]) << 32UL) | | 256 | buid = (((unsigned long)buid_vals[0]) << 32UL) | |
259 | (((unsigned long)buid_vals[1]) & 0xffffffff); | 257 | (((unsigned long)buid_vals[1]) & 0xffffffff); |
260 | } | 258 | } |
261 | return buid; | 259 | return buid; |
262 | } | 260 | } |
263 | 261 | ||
264 | static int phb_set_bus_ranges(struct device_node *dev, | 262 | static int phb_set_bus_ranges(struct device_node *dev, |
265 | struct pci_controller *phb) | 263 | struct pci_controller *phb) |
266 | { | 264 | { |
267 | const int *bus_range; | 265 | const int *bus_range; |
268 | unsigned int len; | 266 | unsigned int len; |
269 | 267 | ||
270 | bus_range = get_property(dev, "bus-range", &len); | 268 | bus_range = get_property(dev, "bus-range", &len); |
271 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 269 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
272 | return 1; | 270 | return 1; |
273 | } | 271 | } |
274 | 272 | ||
275 | phb->first_busno = bus_range[0]; | 273 | phb->first_busno = bus_range[0]; |
276 | phb->last_busno = bus_range[1]; | 274 | phb->last_busno = bus_range[1]; |
277 | 275 | ||
278 | return 0; | 276 | return 0; |
279 | } | 277 | } |
280 | 278 | ||
281 | int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) | 279 | int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) |
282 | { | 280 | { |
283 | if (is_python(dev)) | 281 | if (is_python(dev)) |
284 | python_countermeasures(dev); | 282 | python_countermeasures(dev); |
285 | 283 | ||
286 | if (phb_set_bus_ranges(dev, phb)) | 284 | if (phb_set_bus_ranges(dev, phb)) |
287 | return 1; | 285 | return 1; |
288 | 286 | ||
289 | phb->ops = &rtas_pci_ops; | 287 | phb->ops = &rtas_pci_ops; |
290 | phb->buid = get_phb_buid(dev); | 288 | phb->buid = get_phb_buid(dev); |
291 | 289 | ||
292 | return 0; | 290 | return 0; |
293 | } | 291 | } |
294 | 292 | ||
295 | unsigned long __init find_and_init_phbs(void) | 293 | unsigned long __init find_and_init_phbs(void) |
296 | { | 294 | { |
297 | struct device_node *node; | 295 | struct device_node *node; |
298 | struct pci_controller *phb; | 296 | struct pci_controller *phb; |
299 | unsigned int index; | 297 | unsigned int index; |
300 | struct device_node *root = of_find_node_by_path("/"); | 298 | struct device_node *root = of_find_node_by_path("/"); |
301 | 299 | ||
302 | index = 0; | 300 | index = 0; |
303 | for (node = of_get_next_child(root, NULL); | 301 | for (node = of_get_next_child(root, NULL); |
304 | node != NULL; | 302 | node != NULL; |
305 | node = of_get_next_child(root, node)) { | 303 | node = of_get_next_child(root, node)) { |
306 | 304 | ||
307 | if (node->type == NULL || (strcmp(node->type, "pci") != 0 && | 305 | if (node->type == NULL || (strcmp(node->type, "pci") != 0 && |
308 | strcmp(node->type, "pciex") != 0)) | 306 | strcmp(node->type, "pciex") != 0)) |
309 | continue; | 307 | continue; |
310 | 308 | ||
311 | phb = pcibios_alloc_controller(node); | 309 | phb = pcibios_alloc_controller(node); |
312 | if (!phb) | 310 | if (!phb) |
313 | continue; | 311 | continue; |
314 | setup_phb(node, phb); | 312 | setup_phb(node, phb); |
315 | pci_process_bridge_OF_ranges(phb, node, 0); | 313 | pci_process_bridge_OF_ranges(phb, node, 0); |
316 | pci_setup_phb_io(phb, index == 0); | 314 | pci_setup_phb_io(phb, index == 0); |
317 | index++; | 315 | index++; |
318 | } | 316 | } |
319 | 317 | ||
320 | of_node_put(root); | 318 | of_node_put(root); |
321 | pci_devs_phb_init(); | 319 | pci_devs_phb_init(); |
322 | 320 | ||
323 | /* | 321 | /* |
324 | * pci_probe_only and pci_assign_all_buses can be set via properties | 322 | * pci_probe_only and pci_assign_all_buses can be set via properties |
325 | * in chosen. | 323 | * in chosen. |
326 | */ | 324 | */ |
327 | if (of_chosen) { | 325 | if (of_chosen) { |
328 | const int *prop; | 326 | const int *prop; |
329 | 327 | ||
330 | prop = get_property(of_chosen, | 328 | prop = get_property(of_chosen, |
331 | "linux,pci-probe-only", NULL); | 329 | "linux,pci-probe-only", NULL); |
332 | if (prop) | 330 | if (prop) |
333 | pci_probe_only = *prop; | 331 | pci_probe_only = *prop; |
334 | 332 | ||
335 | prop = get_property(of_chosen, | 333 | prop = get_property(of_chosen, |
336 | "linux,pci-assign-all-buses", NULL); | 334 | "linux,pci-assign-all-buses", NULL); |
337 | if (prop) | 335 | if (prop) |
338 | pci_assign_all_buses = *prop; | 336 | pci_assign_all_buses = *prop; |
339 | } | 337 | } |
340 | 338 | ||
341 | return 0; | 339 | return 0; |
342 | } | 340 | } |
343 | 341 | ||
344 | /* RPA-specific bits for removing PHBs */ | 342 | /* RPA-specific bits for removing PHBs */ |
345 | int pcibios_remove_root_bus(struct pci_controller *phb) | 343 | int pcibios_remove_root_bus(struct pci_controller *phb) |
346 | { | 344 | { |
347 | struct pci_bus *b = phb->bus; | 345 | struct pci_bus *b = phb->bus; |
348 | struct resource *res; | 346 | struct resource *res; |
349 | int rc, i; | 347 | int rc, i; |
350 | 348 | ||
351 | res = b->resource[0]; | 349 | res = b->resource[0]; |
352 | if (!res->flags) { | 350 | if (!res->flags) { |
353 | printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__, | 351 | printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__, |
354 | b->name); | 352 | b->name); |
355 | return 1; | 353 | return 1; |
356 | } | 354 | } |
357 | 355 | ||
358 | rc = unmap_bus_range(b); | 356 | rc = unmap_bus_range(b); |
359 | if (rc) { | 357 | if (rc) { |
360 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | 358 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", |
361 | __FUNCTION__, b->name); | 359 | __FUNCTION__, b->name); |
362 | return 1; | 360 | return 1; |
363 | } | 361 | } |
364 | 362 | ||
365 | if (release_resource(res)) { | 363 | if (release_resource(res)) { |
366 | printk(KERN_ERR "%s: failed to release IO on bus %s\n", | 364 | printk(KERN_ERR "%s: failed to release IO on bus %s\n", |
367 | __FUNCTION__, b->name); | 365 | __FUNCTION__, b->name); |
368 | return 1; | 366 | return 1; |
369 | } | 367 | } |
370 | 368 | ||
371 | for (i = 1; i < 3; ++i) { | 369 | for (i = 1; i < 3; ++i) { |
372 | res = b->resource[i]; | 370 | res = b->resource[i]; |
373 | if (!res->flags && i == 0) { | 371 | if (!res->flags && i == 0) { |
374 | printk(KERN_ERR "%s: no MEM resource for PHB %s\n", | 372 | printk(KERN_ERR "%s: no MEM resource for PHB %s\n", |
375 | __FUNCTION__, b->name); | 373 | __FUNCTION__, b->name); |
376 | return 1; | 374 | return 1; |
377 | } | 375 | } |
378 | if (res->flags && release_resource(res)) { | 376 | if (res->flags && release_resource(res)) { |
379 | printk(KERN_ERR | 377 | printk(KERN_ERR |
380 | "%s: failed to release IO %d on bus %s\n", | 378 | "%s: failed to release IO %d on bus %s\n", |
381 | __FUNCTION__, i, b->name); | 379 | __FUNCTION__, i, b->name); |
382 | return 1; | 380 | return 1; |
383 | } | 381 | } |
384 | } | 382 | } |
385 | 383 | ||
386 | list_del(&phb->list_node); | 384 | list_del(&phb->list_node); |
387 | pcibios_free_controller(phb); | 385 | pcibios_free_controller(phb); |
388 | 386 | ||
389 | return 0; | 387 | return 0; |
390 | } | 388 | } |
391 | EXPORT_SYMBOL(pcibios_remove_root_bus); | 389 | EXPORT_SYMBOL(pcibios_remove_root_bus); |
392 | 390 |
include/asm-powerpc/rtas.h
1 | #ifndef _POWERPC_RTAS_H | 1 | #ifndef _POWERPC_RTAS_H |
2 | #define _POWERPC_RTAS_H | 2 | #define _POWERPC_RTAS_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <asm/page.h> | 6 | #include <asm/page.h> |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Definitions for talking to the RTAS on CHRP machines. | 9 | * Definitions for talking to the RTAS on CHRP machines. |
10 | * | 10 | * |
11 | * Copyright (C) 2001 Peter Bergner | 11 | * Copyright (C) 2001 Peter Bergner |
12 | * Copyright (C) 2001 PPC 64 Team, IBM Corp | 12 | * Copyright (C) 2001 PPC 64 Team, IBM Corp |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
16 | * as published by the Free Software Foundation; either version | 16 | * as published by the Free Software Foundation; either version |
17 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define RTAS_UNKNOWN_SERVICE (-1) | 20 | #define RTAS_UNKNOWN_SERVICE (-1) |
21 | #define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ | 21 | #define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ |
22 | 22 | ||
23 | /* Buffer size for ppc_rtas system call. */ | 23 | /* Buffer size for ppc_rtas system call. */ |
24 | #define RTAS_RMOBUF_MAX (64 * 1024) | 24 | #define RTAS_RMOBUF_MAX (64 * 1024) |
25 | 25 | ||
26 | /* RTAS return status codes */ | 26 | /* RTAS return status codes */ |
27 | #define RTAS_NOT_SUSPENDABLE -9004 | 27 | #define RTAS_NOT_SUSPENDABLE -9004 |
28 | #define RTAS_BUSY -2 /* RTAS Busy */ | 28 | #define RTAS_BUSY -2 /* RTAS Busy */ |
29 | #define RTAS_EXTENDED_DELAY_MIN 9900 | 29 | #define RTAS_EXTENDED_DELAY_MIN 9900 |
30 | #define RTAS_EXTENDED_DELAY_MAX 9905 | 30 | #define RTAS_EXTENDED_DELAY_MAX 9905 |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * In general to call RTAS use rtas_token("string") to lookup | 33 | * In general to call RTAS use rtas_token("string") to lookup |
34 | * an RTAS token for the given string (e.g. "event-scan"). | 34 | * an RTAS token for the given string (e.g. "event-scan"). |
35 | * To actually perform the call use | 35 | * To actually perform the call use |
36 | * ret = rtas_call(token, n_in, n_out, ...) | 36 | * ret = rtas_call(token, n_in, n_out, ...) |
37 | * Where n_in is the number of input parameters and | 37 | * Where n_in is the number of input parameters and |
38 | * n_out is the number of output parameters | 38 | * n_out is the number of output parameters |
39 | * | 39 | * |
40 | * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE | 40 | * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE |
41 | * will be returned as a token. rtas_call() does look for this | 41 | * will be returned as a token. rtas_call() does look for this |
42 | * token and error out gracefully so rtas_call(rtas_token("str"), ...) | 42 | * token and error out gracefully so rtas_call(rtas_token("str"), ...) |
43 | * may be safely used for one-shot calls to RTAS. | 43 | * may be safely used for one-shot calls to RTAS. |
44 | * | 44 | * |
45 | */ | 45 | */ |
46 | 46 | ||
47 | typedef u32 rtas_arg_t; | 47 | typedef u32 rtas_arg_t; |
48 | 48 | ||
49 | struct rtas_args { | 49 | struct rtas_args { |
50 | u32 token; | 50 | u32 token; |
51 | u32 nargs; | 51 | u32 nargs; |
52 | u32 nret; | 52 | u32 nret; |
53 | rtas_arg_t args[16]; | 53 | rtas_arg_t args[16]; |
54 | rtas_arg_t *rets; /* Pointer to return values in args[]. */ | 54 | rtas_arg_t *rets; /* Pointer to return values in args[]. */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | extern struct rtas_args rtas_stop_self_args; | 57 | extern struct rtas_args rtas_stop_self_args; |
58 | 58 | ||
59 | struct rtas_t { | 59 | struct rtas_t { |
60 | unsigned long entry; /* physical address pointer */ | 60 | unsigned long entry; /* physical address pointer */ |
61 | unsigned long base; /* physical address pointer */ | 61 | unsigned long base; /* physical address pointer */ |
62 | unsigned long size; | 62 | unsigned long size; |
63 | spinlock_t lock; | 63 | spinlock_t lock; |
64 | struct rtas_args args; | 64 | struct rtas_args args; |
65 | struct device_node *dev; /* virtual address pointer */ | 65 | struct device_node *dev; /* virtual address pointer */ |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* RTAS event classes */ | 68 | /* RTAS event classes */ |
69 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ | 69 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ |
70 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ | 70 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ |
71 | #define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */ | 71 | #define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */ |
72 | #define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */ | 72 | #define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */ |
73 | #define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000 | 73 | #define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000 |
74 | 74 | ||
75 | /* RTAS event severity */ | 75 | /* RTAS event severity */ |
76 | #define RTAS_SEVERITY_FATAL 0x5 | 76 | #define RTAS_SEVERITY_FATAL 0x5 |
77 | #define RTAS_SEVERITY_ERROR 0x4 | 77 | #define RTAS_SEVERITY_ERROR 0x4 |
78 | #define RTAS_SEVERITY_ERROR_SYNC 0x3 | 78 | #define RTAS_SEVERITY_ERROR_SYNC 0x3 |
79 | #define RTAS_SEVERITY_WARNING 0x2 | 79 | #define RTAS_SEVERITY_WARNING 0x2 |
80 | #define RTAS_SEVERITY_EVENT 0x1 | 80 | #define RTAS_SEVERITY_EVENT 0x1 |
81 | #define RTAS_SEVERITY_NO_ERROR 0x0 | 81 | #define RTAS_SEVERITY_NO_ERROR 0x0 |
82 | 82 | ||
83 | /* RTAS event disposition */ | 83 | /* RTAS event disposition */ |
84 | #define RTAS_DISP_FULLY_RECOVERED 0x0 | 84 | #define RTAS_DISP_FULLY_RECOVERED 0x0 |
85 | #define RTAS_DISP_LIMITED_RECOVERY 0x1 | 85 | #define RTAS_DISP_LIMITED_RECOVERY 0x1 |
86 | #define RTAS_DISP_NOT_RECOVERED 0x2 | 86 | #define RTAS_DISP_NOT_RECOVERED 0x2 |
87 | 87 | ||
88 | /* RTAS event initiator */ | 88 | /* RTAS event initiator */ |
89 | #define RTAS_INITIATOR_UNKNOWN 0x0 | 89 | #define RTAS_INITIATOR_UNKNOWN 0x0 |
90 | #define RTAS_INITIATOR_CPU 0x1 | 90 | #define RTAS_INITIATOR_CPU 0x1 |
91 | #define RTAS_INITIATOR_PCI 0x2 | 91 | #define RTAS_INITIATOR_PCI 0x2 |
92 | #define RTAS_INITIATOR_ISA 0x3 | 92 | #define RTAS_INITIATOR_ISA 0x3 |
93 | #define RTAS_INITIATOR_MEMORY 0x4 | 93 | #define RTAS_INITIATOR_MEMORY 0x4 |
94 | #define RTAS_INITIATOR_POWERMGM 0x5 | 94 | #define RTAS_INITIATOR_POWERMGM 0x5 |
95 | 95 | ||
96 | /* RTAS event target */ | 96 | /* RTAS event target */ |
97 | #define RTAS_TARGET_UNKNOWN 0x0 | 97 | #define RTAS_TARGET_UNKNOWN 0x0 |
98 | #define RTAS_TARGET_CPU 0x1 | 98 | #define RTAS_TARGET_CPU 0x1 |
99 | #define RTAS_TARGET_PCI 0x2 | 99 | #define RTAS_TARGET_PCI 0x2 |
100 | #define RTAS_TARGET_ISA 0x3 | 100 | #define RTAS_TARGET_ISA 0x3 |
101 | #define RTAS_TARGET_MEMORY 0x4 | 101 | #define RTAS_TARGET_MEMORY 0x4 |
102 | #define RTAS_TARGET_POWERMGM 0x5 | 102 | #define RTAS_TARGET_POWERMGM 0x5 |
103 | 103 | ||
104 | /* RTAS event type */ | 104 | /* RTAS event type */ |
105 | #define RTAS_TYPE_RETRY 0x01 | 105 | #define RTAS_TYPE_RETRY 0x01 |
106 | #define RTAS_TYPE_TCE_ERR 0x02 | 106 | #define RTAS_TYPE_TCE_ERR 0x02 |
107 | #define RTAS_TYPE_INTERN_DEV_FAIL 0x03 | 107 | #define RTAS_TYPE_INTERN_DEV_FAIL 0x03 |
108 | #define RTAS_TYPE_TIMEOUT 0x04 | 108 | #define RTAS_TYPE_TIMEOUT 0x04 |
109 | #define RTAS_TYPE_DATA_PARITY 0x05 | 109 | #define RTAS_TYPE_DATA_PARITY 0x05 |
110 | #define RTAS_TYPE_ADDR_PARITY 0x06 | 110 | #define RTAS_TYPE_ADDR_PARITY 0x06 |
111 | #define RTAS_TYPE_CACHE_PARITY 0x07 | 111 | #define RTAS_TYPE_CACHE_PARITY 0x07 |
112 | #define RTAS_TYPE_ADDR_INVALID 0x08 | 112 | #define RTAS_TYPE_ADDR_INVALID 0x08 |
113 | #define RTAS_TYPE_ECC_UNCORR 0x09 | 113 | #define RTAS_TYPE_ECC_UNCORR 0x09 |
114 | #define RTAS_TYPE_ECC_CORR 0x0a | 114 | #define RTAS_TYPE_ECC_CORR 0x0a |
115 | #define RTAS_TYPE_EPOW 0x40 | 115 | #define RTAS_TYPE_EPOW 0x40 |
116 | #define RTAS_TYPE_PLATFORM 0xE0 | 116 | #define RTAS_TYPE_PLATFORM 0xE0 |
117 | #define RTAS_TYPE_IO 0xE1 | 117 | #define RTAS_TYPE_IO 0xE1 |
118 | #define RTAS_TYPE_INFO 0xE2 | 118 | #define RTAS_TYPE_INFO 0xE2 |
119 | #define RTAS_TYPE_DEALLOC 0xE3 | 119 | #define RTAS_TYPE_DEALLOC 0xE3 |
120 | #define RTAS_TYPE_DUMP 0xE4 | 120 | #define RTAS_TYPE_DUMP 0xE4 |
121 | /* I don't add PowerMGM events right now, this is a different topic */ | 121 | /* I don't add PowerMGM events right now, this is a different topic */ |
122 | #define RTAS_TYPE_PMGM_POWER_SW_ON 0x60 | 122 | #define RTAS_TYPE_PMGM_POWER_SW_ON 0x60 |
123 | #define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61 | 123 | #define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61 |
124 | #define RTAS_TYPE_PMGM_LID_OPEN 0x62 | 124 | #define RTAS_TYPE_PMGM_LID_OPEN 0x62 |
125 | #define RTAS_TYPE_PMGM_LID_CLOSE 0x63 | 125 | #define RTAS_TYPE_PMGM_LID_CLOSE 0x63 |
126 | #define RTAS_TYPE_PMGM_SLEEP_BTN 0x64 | 126 | #define RTAS_TYPE_PMGM_SLEEP_BTN 0x64 |
127 | #define RTAS_TYPE_PMGM_WAKE_BTN 0x65 | 127 | #define RTAS_TYPE_PMGM_WAKE_BTN 0x65 |
128 | #define RTAS_TYPE_PMGM_BATTERY_WARN 0x66 | 128 | #define RTAS_TYPE_PMGM_BATTERY_WARN 0x66 |
129 | #define RTAS_TYPE_PMGM_BATTERY_CRIT 0x67 | 129 | #define RTAS_TYPE_PMGM_BATTERY_CRIT 0x67 |
130 | #define RTAS_TYPE_PMGM_SWITCH_TO_BAT 0x68 | 130 | #define RTAS_TYPE_PMGM_SWITCH_TO_BAT 0x68 |
131 | #define RTAS_TYPE_PMGM_SWITCH_TO_AC 0x69 | 131 | #define RTAS_TYPE_PMGM_SWITCH_TO_AC 0x69 |
132 | #define RTAS_TYPE_PMGM_KBD_OR_MOUSE 0x6a | 132 | #define RTAS_TYPE_PMGM_KBD_OR_MOUSE 0x6a |
133 | #define RTAS_TYPE_PMGM_ENCLOS_OPEN 0x6b | 133 | #define RTAS_TYPE_PMGM_ENCLOS_OPEN 0x6b |
134 | #define RTAS_TYPE_PMGM_ENCLOS_CLOSED 0x6c | 134 | #define RTAS_TYPE_PMGM_ENCLOS_CLOSED 0x6c |
135 | #define RTAS_TYPE_PMGM_RING_INDICATE 0x6d | 135 | #define RTAS_TYPE_PMGM_RING_INDICATE 0x6d |
136 | #define RTAS_TYPE_PMGM_LAN_ATTENTION 0x6e | 136 | #define RTAS_TYPE_PMGM_LAN_ATTENTION 0x6e |
137 | #define RTAS_TYPE_PMGM_TIME_ALARM 0x6f | 137 | #define RTAS_TYPE_PMGM_TIME_ALARM 0x6f |
138 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 | 138 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 |
139 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 | 139 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 |
140 | 140 | ||
141 | struct rtas_error_log { | 141 | struct rtas_error_log { |
142 | unsigned long version:8; /* Architectural version */ | 142 | unsigned long version:8; /* Architectural version */ |
143 | unsigned long severity:3; /* Severity level of error */ | 143 | unsigned long severity:3; /* Severity level of error */ |
144 | unsigned long disposition:2; /* Degree of recovery */ | 144 | unsigned long disposition:2; /* Degree of recovery */ |
145 | unsigned long extended:1; /* extended log present? */ | 145 | unsigned long extended:1; /* extended log present? */ |
146 | unsigned long /* reserved */ :2; /* Reserved for future use */ | 146 | unsigned long /* reserved */ :2; /* Reserved for future use */ |
147 | unsigned long initiator:4; /* Initiator of event */ | 147 | unsigned long initiator:4; /* Initiator of event */ |
148 | unsigned long target:4; /* Target of failed operation */ | 148 | unsigned long target:4; /* Target of failed operation */ |
149 | unsigned long type:8; /* General event or error*/ | 149 | unsigned long type:8; /* General event or error*/ |
150 | unsigned long extended_log_length:32; /* length in bytes */ | 150 | unsigned long extended_log_length:32; /* length in bytes */ |
151 | unsigned char buffer[1]; | 151 | unsigned char buffer[1]; |
152 | }; | 152 | }; |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * This can be set by the rtas_flash module so that it can get called | 155 | * This can be set by the rtas_flash module so that it can get called |
156 | * as the absolutely last thing before the kernel terminates. | 156 | * as the absolutely last thing before the kernel terminates. |
157 | */ | 157 | */ |
158 | extern void (*rtas_flash_term_hook)(int); | 158 | extern void (*rtas_flash_term_hook)(int); |
159 | 159 | ||
160 | extern struct rtas_t rtas; | 160 | extern struct rtas_t rtas; |
161 | 161 | ||
162 | extern void enter_rtas(unsigned long); | 162 | extern void enter_rtas(unsigned long); |
163 | extern int rtas_token(const char *service); | 163 | extern int rtas_token(const char *service); |
164 | extern int rtas_call(int token, int, int, int *, ...); | 164 | extern int rtas_call(int token, int, int, int *, ...); |
165 | extern void rtas_restart(char *cmd); | 165 | extern void rtas_restart(char *cmd); |
166 | extern void rtas_power_off(void); | 166 | extern void rtas_power_off(void); |
167 | extern void rtas_halt(void); | 167 | extern void rtas_halt(void); |
168 | extern void rtas_os_term(char *str); | 168 | extern void rtas_os_term(char *str); |
169 | extern int rtas_get_sensor(int sensor, int index, int *state); | 169 | extern int rtas_get_sensor(int sensor, int index, int *state); |
170 | extern int rtas_get_power_level(int powerdomain, int *level); | 170 | extern int rtas_get_power_level(int powerdomain, int *level); |
171 | extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); | 171 | extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); |
172 | extern int rtas_set_indicator(int indicator, int index, int new_value); | 172 | extern int rtas_set_indicator(int indicator, int index, int new_value); |
173 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); | 173 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); |
174 | extern void rtas_progress(char *s, unsigned short hex); | 174 | extern void rtas_progress(char *s, unsigned short hex); |
175 | extern void rtas_initialize(void); | 175 | extern void rtas_initialize(void); |
176 | 176 | ||
177 | struct rtc_time; | 177 | struct rtc_time; |
178 | extern unsigned long rtas_get_boot_time(void); | 178 | extern unsigned long rtas_get_boot_time(void); |
179 | extern void rtas_get_rtc_time(struct rtc_time *rtc_time); | 179 | extern void rtas_get_rtc_time(struct rtc_time *rtc_time); |
180 | extern int rtas_set_rtc_time(struct rtc_time *rtc_time); | 180 | extern int rtas_set_rtc_time(struct rtc_time *rtc_time); |
181 | 181 | ||
182 | extern unsigned int rtas_busy_delay_time(int status); | 182 | extern unsigned int rtas_busy_delay_time(int status); |
183 | extern unsigned int rtas_busy_delay(int status); | 183 | extern unsigned int rtas_busy_delay(int status); |
184 | 184 | ||
185 | extern int early_init_dt_scan_rtas(unsigned long node, | 185 | extern int early_init_dt_scan_rtas(unsigned long node, |
186 | const char *uname, int depth, void *data); | 186 | const char *uname, int depth, void *data); |
187 | 187 | ||
188 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); | 188 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); |
189 | 189 | ||
190 | /* Error types logged. */ | 190 | /* Error types logged. */ |
191 | #define ERR_FLAG_ALREADY_LOGGED 0x0 | 191 | #define ERR_FLAG_ALREADY_LOGGED 0x0 |
192 | #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ | 192 | #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ |
193 | #define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ | 193 | #define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ |
194 | #define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ | 194 | #define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ |
195 | 195 | ||
196 | /* All the types and not flags */ | 196 | /* All the types and not flags */ |
197 | #define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) | 197 | #define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) |
198 | 198 | ||
199 | #define RTAS_DEBUG KERN_DEBUG "RTAS: " | 199 | #define RTAS_DEBUG KERN_DEBUG "RTAS: " |
200 | 200 | ||
201 | #define RTAS_ERROR_LOG_MAX 2048 | 201 | #define RTAS_ERROR_LOG_MAX 2048 |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * Return the firmware-specified size of the error log buffer | 204 | * Return the firmware-specified size of the error log buffer |
205 | * for all rtas calls that require an error buffer argument. | 205 | * for all rtas calls that require an error buffer argument. |
206 | * This includes 'check-exception' and 'rtas-last-error'. | 206 | * This includes 'check-exception' and 'rtas-last-error'. |
207 | */ | 207 | */ |
208 | extern int rtas_get_error_log_max(void); | 208 | extern int rtas_get_error_log_max(void); |
209 | 209 | ||
210 | /* Event Scan Parameters */ | 210 | /* Event Scan Parameters */ |
211 | #define EVENT_SCAN_ALL_EVENTS 0xf0000000 | 211 | #define EVENT_SCAN_ALL_EVENTS 0xf0000000 |
212 | #define SURVEILLANCE_TOKEN 9000 | 212 | #define SURVEILLANCE_TOKEN 9000 |
213 | #define LOG_NUMBER 64 /* must be a power of two */ | 213 | #define LOG_NUMBER 64 /* must be a power of two */ |
214 | #define LOG_NUMBER_MASK (LOG_NUMBER-1) | 214 | #define LOG_NUMBER_MASK (LOG_NUMBER-1) |
215 | 215 | ||
216 | /* Some RTAS ops require a data buffer and that buffer must be < 4G. | 216 | /* Some RTAS ops require a data buffer and that buffer must be < 4G. |
217 | * Rather than having a memory allocator, just use this buffer | 217 | * Rather than having a memory allocator, just use this buffer |
218 | * (get the lock first), make the RTAS call. Copy the data instead | 218 | * (get the lock first), make the RTAS call. Copy the data instead |
219 | * of holding the buffer for long. | 219 | * of holding the buffer for long. |
220 | */ | 220 | */ |
221 | 221 | ||
222 | #define RTAS_DATA_BUF_SIZE 4096 | 222 | #define RTAS_DATA_BUF_SIZE 4096 |
223 | extern spinlock_t rtas_data_buf_lock; | 223 | extern spinlock_t rtas_data_buf_lock; |
224 | extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; | 224 | extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; |
225 | 225 | ||
226 | extern void rtas_stop_self(void); | 226 | extern void rtas_stop_self(void); |
227 | 227 | ||
228 | /* RMO buffer reserved for user-space RTAS use */ | 228 | /* RMO buffer reserved for user-space RTAS use */ |
229 | extern unsigned long rtas_rmo_buf; | 229 | extern unsigned long rtas_rmo_buf; |
230 | 230 | ||
231 | #define GLOBAL_INTERRUPT_QUEUE 9005 | 231 | #define GLOBAL_INTERRUPT_QUEUE 9005 |
232 | 232 | ||
233 | /** | ||
234 | * rtas_config_addr - Format a busno, devfn and reg for RTAS. | ||
235 | * @busno: The bus number. | ||
236 | * @devfn: The device and function number as encoded by PCI_DEVFN(). | ||
237 | * @reg: The register number. | ||
238 | * | ||
239 | * This function encodes the given busno, devfn and register number as | ||
240 | * required for RTAS calls that take a "config_addr" parameter. | ||
241 | * See PAPR requirement 7.3.4-1 for more info. | ||
242 | */ | ||
243 | static inline u32 rtas_config_addr(int busno, int devfn, int reg) | ||
244 | { | ||
245 | return ((reg & 0xf00) << 20) | ((busno & 0xff) << 16) | | ||
246 | (devfn << 8) | (reg & 0xff); | ||
247 | } | ||
248 | |||
233 | #endif /* __KERNEL__ */ | 249 | #endif /* __KERNEL__ */ |
234 | #endif /* _POWERPC_RTAS_H */ | 250 | #endif /* _POWERPC_RTAS_H */ |
235 | 251 |