diff options
Diffstat (limited to 'arch/powerpc/kernel/rtas_pci.c')
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 49 |
1 files changed, 12 insertions, 37 deletions
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 60dec2401c26..45b8109951fe 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -188,39 +188,19 @@ int is_python(struct device_node *dev) | |||
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
190 | 190 | ||
191 | static int get_phb_reg_prop(struct device_node *dev, | 191 | static void python_countermeasures(struct device_node *dev) |
192 | unsigned int addr_size_words, | ||
193 | struct reg_property64 *reg) | ||
194 | { | 192 | { |
195 | unsigned int *ui_ptr = NULL, len; | 193 | struct resource registers; |
196 | |||
197 | /* Found a PHB, now figure out where his registers are mapped. */ | ||
198 | ui_ptr = (unsigned int *)get_property(dev, "reg", &len); | ||
199 | if (ui_ptr == NULL) | ||
200 | return 1; | ||
201 | |||
202 | if (addr_size_words == 1) { | ||
203 | reg->address = ((struct reg_property32 *)ui_ptr)->address; | ||
204 | reg->size = ((struct reg_property32 *)ui_ptr)->size; | ||
205 | } else { | ||
206 | *reg = *((struct reg_property64 *)ui_ptr); | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static void python_countermeasures(struct device_node *dev, | ||
213 | unsigned int addr_size_words) | ||
214 | { | ||
215 | struct reg_property64 reg_struct; | ||
216 | void __iomem *chip_regs; | 194 | void __iomem *chip_regs; |
217 | volatile u32 val; | 195 | volatile u32 val; |
218 | 196 | ||
219 | if (get_phb_reg_prop(dev, addr_size_words, ®_struct)) | 197 | if (of_address_to_resource(dev, 0, ®isters)) { |
198 | printk(KERN_ERR "Can't get address for Python workarounds !\n"); | ||
220 | return; | 199 | return; |
200 | } | ||
221 | 201 | ||
222 | /* Python's register file is 1 MB in size. */ | 202 | /* Python's register file is 1 MB in size. */ |
223 | chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); | 203 | chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000); |
224 | 204 | ||
225 | /* | 205 | /* |
226 | * Firmware doesn't always clear this bit which is critical | 206 | * Firmware doesn't always clear this bit which is critical |
@@ -301,11 +281,10 @@ static int phb_set_bus_ranges(struct device_node *dev, | |||
301 | } | 281 | } |
302 | 282 | ||
303 | static int __devinit setup_phb(struct device_node *dev, | 283 | static int __devinit setup_phb(struct device_node *dev, |
304 | struct pci_controller *phb, | 284 | struct pci_controller *phb) |
305 | unsigned int addr_size_words) | ||
306 | { | 285 | { |
307 | if (is_python(dev)) | 286 | if (is_python(dev)) |
308 | python_countermeasures(dev, addr_size_words); | 287 | python_countermeasures(dev); |
309 | 288 | ||
310 | if (phb_set_bus_ranges(dev, phb)) | 289 | if (phb_set_bus_ranges(dev, phb)) |
311 | return 1; | 290 | return 1; |
@@ -320,8 +299,8 @@ unsigned long __init find_and_init_phbs(void) | |||
320 | { | 299 | { |
321 | struct device_node *node; | 300 | struct device_node *node; |
322 | struct pci_controller *phb; | 301 | struct pci_controller *phb; |
323 | unsigned int root_size_cells = 0; | ||
324 | unsigned int index; | 302 | unsigned int index; |
303 | unsigned int root_size_cells = 0; | ||
325 | unsigned int *opprop = NULL; | 304 | unsigned int *opprop = NULL; |
326 | struct device_node *root = of_find_node_by_path("/"); | 305 | struct device_node *root = of_find_node_by_path("/"); |
327 | 306 | ||
@@ -343,10 +322,11 @@ unsigned long __init find_and_init_phbs(void) | |||
343 | phb = pcibios_alloc_controller(node); | 322 | phb = pcibios_alloc_controller(node); |
344 | if (!phb) | 323 | if (!phb) |
345 | continue; | 324 | continue; |
346 | setup_phb(node, phb, root_size_cells); | 325 | setup_phb(node, phb); |
347 | pci_process_bridge_OF_ranges(phb, node, 0); | 326 | pci_process_bridge_OF_ranges(phb, node, 0); |
348 | pci_setup_phb_io(phb, index == 0); | 327 | pci_setup_phb_io(phb, index == 0); |
349 | #ifdef CONFIG_PPC_PSERIES | 328 | #ifdef CONFIG_PPC_PSERIES |
329 | /* XXX This code need serious fixing ... --BenH */ | ||
350 | if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { | 330 | if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { |
351 | int addr = root_size_cells * (index + 2) - 1; | 331 | int addr = root_size_cells * (index + 2) - 1; |
352 | mpic_assign_isu(pSeries_mpic, index, opprop[addr]); | 332 | mpic_assign_isu(pSeries_mpic, index, opprop[addr]); |
@@ -381,22 +361,17 @@ unsigned long __init find_and_init_phbs(void) | |||
381 | 361 | ||
382 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | 362 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) |
383 | { | 363 | { |
384 | struct device_node *root = of_find_node_by_path("/"); | ||
385 | unsigned int root_size_cells = 0; | ||
386 | struct pci_controller *phb; | 364 | struct pci_controller *phb; |
387 | int primary; | 365 | int primary; |
388 | 366 | ||
389 | root_size_cells = prom_n_size_cells(root); | ||
390 | |||
391 | primary = list_empty(&hose_list); | 367 | primary = list_empty(&hose_list); |
392 | phb = pcibios_alloc_controller(dn); | 368 | phb = pcibios_alloc_controller(dn); |
393 | if (!phb) | 369 | if (!phb) |
394 | return NULL; | 370 | return NULL; |
395 | setup_phb(dn, phb, root_size_cells); | 371 | setup_phb(dn, phb); |
396 | pci_process_bridge_OF_ranges(phb, dn, primary); | 372 | pci_process_bridge_OF_ranges(phb, dn, primary); |
397 | 373 | ||
398 | pci_setup_phb_io_dynamic(phb, primary); | 374 | pci_setup_phb_io_dynamic(phb, primary); |
399 | of_node_put(root); | ||
400 | 375 | ||
401 | pci_devs_phb_init_dynamic(phb); | 376 | pci_devs_phb_init_dynamic(phb); |
402 | scan_phb(phb); | 377 | scan_phb(phb); |