Commit 1635317facea3094ddf34082cd86797efb1d9f7e
1 parent
b28d2582ce
Exists in
master
and in
4 other branches
[PATCH] Separate pci bits out of struct device_node
This patch pulls the PCI-related junk out of struct device_node and puts it in a separate structure, struct pci_dn. The device_node now just has a void * pointer in it, which points to a struct pci_dn for nodes that represent PCI devices. It could potentially be used in future for device-specific data for other sorts of devices, such as virtual I/O devices. Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 19 changed files with 209 additions and 137 deletions Side-by-side Diff
- arch/ppc64/kernel/eeh.c
- arch/ppc64/kernel/iommu.c
- arch/ppc64/kernel/maple_pci.c
- arch/ppc64/kernel/pSeries_iommu.c
- arch/ppc64/kernel/pci.c
- arch/ppc64/kernel/pci.h
- arch/ppc64/kernel/pci_dn.c
- arch/ppc64/kernel/pci_iommu.c
- arch/ppc64/kernel/pmac_feature.c
- arch/ppc64/kernel/pmac_pci.c
- arch/ppc64/kernel/prom.c
- arch/ppc64/kernel/rtas_pci.c
- arch/ppc64/kernel/sys_ppc32.c
- arch/ppc64/kernel/u3_iommu.c
- drivers/pci/hotplug/rpadlpar_core.c
- drivers/pci/hotplug/rpaphp_pci.c
- drivers/video/offb.c
- include/asm-ppc64/pci-bridge.h
- include/asm-ppc64/prom.h
arch/ppc64/kernel/eeh.c
| ... | ... | @@ -254,6 +254,7 @@ |
| 254 | 254 | static void __pci_addr_cache_insert_device(struct pci_dev *dev) |
| 255 | 255 | { |
| 256 | 256 | struct device_node *dn; |
| 257 | + struct pci_dn *pdn; | |
| 257 | 258 | int i; |
| 258 | 259 | int inserted = 0; |
| 259 | 260 | |
| ... | ... | @@ -265,8 +266,9 @@ |
| 265 | 266 | } |
| 266 | 267 | |
| 267 | 268 | /* Skip any devices for which EEH is not enabled. */ |
| 268 | - if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || | |
| 269 | - dn->eeh_mode & EEH_MODE_NOCHECK) { | |
| 269 | + pdn = dn->data; | |
| 270 | + if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | |
| 271 | + pdn->eeh_mode & EEH_MODE_NOCHECK) { | |
| 270 | 272 | #ifdef DEBUG |
| 271 | 273 | printk(KERN_INFO "PCI: skip building address cache for=%s\n", |
| 272 | 274 | pci_name(dev)); |
| ... | ... | @@ -415,6 +417,7 @@ |
| 415 | 417 | static int read_slot_reset_state(struct device_node *dn, int rets[]) |
| 416 | 418 | { |
| 417 | 419 | int token, outputs; |
| 420 | + struct pci_dn *pdn = dn->data; | |
| 418 | 421 | |
| 419 | 422 | if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { |
| 420 | 423 | token = ibm_read_slot_reset_state2; |
| ... | ... | @@ -424,8 +427,8 @@ |
| 424 | 427 | outputs = 3; |
| 425 | 428 | } |
| 426 | 429 | |
| 427 | - return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, | |
| 428 | - BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); | |
| 430 | + return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr, | |
| 431 | + BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid)); | |
| 429 | 432 | } |
| 430 | 433 | |
| 431 | 434 | /** |
| ... | ... | @@ -534,6 +537,7 @@ |
| 534 | 537 | unsigned long flags; |
| 535 | 538 | int rc, reset_state; |
| 536 | 539 | struct eeh_event *event; |
| 540 | + struct pci_dn *pdn; | |
| 537 | 541 | |
| 538 | 542 | __get_cpu_var(total_mmio_ffs)++; |
| 539 | 543 | |
| 540 | 544 | |
| 541 | 545 | |
| ... | ... | @@ -542,14 +546,15 @@ |
| 542 | 546 | |
| 543 | 547 | if (!dn) |
| 544 | 548 | return 0; |
| 549 | + pdn = dn->data; | |
| 545 | 550 | |
| 546 | 551 | /* Access to IO BARs might get this far and still not want checking. */ |
| 547 | - if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || | |
| 548 | - dn->eeh_mode & EEH_MODE_NOCHECK) { | |
| 552 | + if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | |
| 553 | + pdn->eeh_mode & EEH_MODE_NOCHECK) { | |
| 549 | 554 | return 0; |
| 550 | 555 | } |
| 551 | 556 | |
| 552 | - if (!dn->eeh_config_addr) { | |
| 557 | + if (!pdn->eeh_config_addr) { | |
| 553 | 558 | return 0; |
| 554 | 559 | } |
| 555 | 560 | |
| ... | ... | @@ -557,7 +562,7 @@ |
| 557 | 562 | * If we already have a pending isolation event for this |
| 558 | 563 | * slot, we know it's bad already, we don't need to check... |
| 559 | 564 | */ |
| 560 | - if (dn->eeh_mode & EEH_MODE_ISOLATED) { | |
| 565 | + if (pdn->eeh_mode & EEH_MODE_ISOLATED) { | |
| 561 | 566 | atomic_inc(&eeh_fail_count); |
| 562 | 567 | if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { |
| 563 | 568 | /* re-read the slot reset state */ |
| ... | ... | @@ -582,7 +587,7 @@ |
| 582 | 587 | } |
| 583 | 588 | |
| 584 | 589 | /* prevent repeated reports of this failure */ |
| 585 | - dn->eeh_mode |= EEH_MODE_ISOLATED; | |
| 590 | + pdn->eeh_mode |= EEH_MODE_ISOLATED; | |
| 586 | 591 | |
| 587 | 592 | reset_state = rets[0]; |
| 588 | 593 | |
| ... | ... | @@ -590,9 +595,9 @@ |
| 590 | 595 | memset(slot_errbuf, 0, eeh_error_buf_size); |
| 591 | 596 | |
| 592 | 597 | rc = rtas_call(ibm_slot_error_detail, |
| 593 | - 8, 1, NULL, dn->eeh_config_addr, | |
| 594 | - BUID_HI(dn->phb->buid), | |
| 595 | - BUID_LO(dn->phb->buid), NULL, 0, | |
| 598 | + 8, 1, NULL, pdn->eeh_config_addr, | |
| 599 | + BUID_HI(pdn->phb->buid), | |
| 600 | + BUID_LO(pdn->phb->buid), NULL, 0, | |
| 596 | 601 | virt_to_phys(slot_errbuf), |
| 597 | 602 | eeh_error_buf_size, |
| 598 | 603 | 1 /* Temporary Error */); |
| 599 | 604 | |
| ... | ... | @@ -679,8 +684,9 @@ |
| 679 | 684 | u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); |
| 680 | 685 | u32 *regs; |
| 681 | 686 | int enable; |
| 687 | + struct pci_dn *pdn = dn->data; | |
| 682 | 688 | |
| 683 | - dn->eeh_mode = 0; | |
| 689 | + pdn->eeh_mode = 0; | |
| 684 | 690 | |
| 685 | 691 | if (status && strcmp(status, "ok") != 0) |
| 686 | 692 | return NULL; /* ignore devices with bad status */ |
| ... | ... | @@ -691,7 +697,7 @@ |
| 691 | 697 | |
| 692 | 698 | /* There is nothing to check on PCI to ISA bridges */ |
| 693 | 699 | if (dn->type && !strcmp(dn->type, "isa")) { |
| 694 | - dn->eeh_mode |= EEH_MODE_NOCHECK; | |
| 700 | + pdn->eeh_mode |= EEH_MODE_NOCHECK; | |
| 695 | 701 | return NULL; |
| 696 | 702 | } |
| 697 | 703 | |
| ... | ... | @@ -708,7 +714,7 @@ |
| 708 | 714 | enable = 0; |
| 709 | 715 | |
| 710 | 716 | if (!enable) |
| 711 | - dn->eeh_mode |= EEH_MODE_NOCHECK; | |
| 717 | + pdn->eeh_mode |= EEH_MODE_NOCHECK; | |
| 712 | 718 | |
| 713 | 719 | /* Ok... see if this device supports EEH. Some do, some don't, |
| 714 | 720 | * and the only way to find out is to check each and every one. */ |
| ... | ... | @@ -721,8 +727,8 @@ |
| 721 | 727 | EEH_ENABLE); |
| 722 | 728 | if (ret == 0) { |
| 723 | 729 | eeh_subsystem_enabled = 1; |
| 724 | - dn->eeh_mode |= EEH_MODE_SUPPORTED; | |
| 725 | - dn->eeh_config_addr = regs[0]; | |
| 730 | + pdn->eeh_mode |= EEH_MODE_SUPPORTED; | |
| 731 | + pdn->eeh_config_addr = regs[0]; | |
| 726 | 732 | #ifdef DEBUG |
| 727 | 733 | printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); |
| 728 | 734 | #endif |
| 729 | 735 | |
| ... | ... | @@ -730,10 +736,11 @@ |
| 730 | 736 | |
| 731 | 737 | /* This device doesn't support EEH, but it may have an |
| 732 | 738 | * EEH parent, in which case we mark it as supported. */ |
| 733 | - if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { | |
| 739 | + if (dn->parent && dn->parent->data | |
| 740 | + && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { | |
| 734 | 741 | /* Parent supports EEH. */ |
| 735 | - dn->eeh_mode |= EEH_MODE_SUPPORTED; | |
| 736 | - dn->eeh_config_addr = dn->parent->eeh_config_addr; | |
| 742 | + pdn->eeh_mode |= EEH_MODE_SUPPORTED; | |
| 743 | + pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr; | |
| 737 | 744 | return NULL; |
| 738 | 745 | } |
| 739 | 746 | } |
| 740 | 747 | |
| 741 | 748 | |
| ... | ... | @@ -790,11 +797,13 @@ |
| 790 | 797 | for (phb = of_find_node_by_name(NULL, "pci"); phb; |
| 791 | 798 | phb = of_find_node_by_name(phb, "pci")) { |
| 792 | 799 | unsigned long buid; |
| 800 | + struct pci_dn *pci; | |
| 793 | 801 | |
| 794 | 802 | buid = get_phb_buid(phb); |
| 795 | - if (buid == 0) | |
| 803 | + if (buid == 0 || phb->data == NULL) | |
| 796 | 804 | continue; |
| 797 | 805 | |
| 806 | + pci = phb->data; | |
| 798 | 807 | info.buid_lo = BUID_LO(buid); |
| 799 | 808 | info.buid_hi = BUID_HI(buid); |
| 800 | 809 | traverse_pci_devices(phb, early_enable_eeh, &info); |
| 801 | 810 | |
| ... | ... | @@ -823,9 +832,9 @@ |
| 823 | 832 | struct pci_controller *phb; |
| 824 | 833 | struct eeh_early_enable_info info; |
| 825 | 834 | |
| 826 | - if (!dn) | |
| 835 | + if (!dn || !dn->data) | |
| 827 | 836 | return; |
| 828 | - phb = dn->phb; | |
| 837 | + phb = PCI_DN(dn)->phb; | |
| 829 | 838 | if (NULL == phb || 0 == phb->buid) { |
| 830 | 839 | printk(KERN_WARNING "EEH: Expected buid but found none\n"); |
| 831 | 840 | return; |
arch/ppc64/kernel/iommu.c
| ... | ... | @@ -438,7 +438,8 @@ |
| 438 | 438 | |
| 439 | 439 | void iommu_free_table(struct device_node *dn) |
| 440 | 440 | { |
| 441 | - struct iommu_table *tbl = dn->iommu_table; | |
| 441 | + struct pci_dn *pdn = dn->data; | |
| 442 | + struct iommu_table *tbl = pdn->iommu_table; | |
| 442 | 443 | unsigned long bitmap_sz, i; |
| 443 | 444 | unsigned int order; |
| 444 | 445 |
arch/ppc64/kernel/maple_pci.c
| ... | ... | @@ -447,9 +447,9 @@ |
| 447 | 447 | */ |
| 448 | 448 | if (u3_agp) { |
| 449 | 449 | struct device_node *np = u3_agp->arch_data; |
| 450 | - np->busno = 0xf0; | |
| 450 | + PCI_DN(np)->busno = 0xf0; | |
| 451 | 451 | for (np = np->child; np; np = np->sibling) |
| 452 | - np->busno = 0xf0; | |
| 452 | + PCI_DN(np)->busno = 0xf0; | |
| 453 | 453 | } |
| 454 | 454 | |
| 455 | 455 | /* Tell pci.c to use the common resource allocation mecanism */ |
arch/ppc64/kernel/pSeries_iommu.c
| ... | ... | @@ -295,7 +295,7 @@ |
| 295 | 295 | struct iommu_table *tbl, |
| 296 | 296 | unsigned int *dma_window) |
| 297 | 297 | { |
| 298 | - tbl->it_busno = dn->bussubno; | |
| 298 | + tbl->it_busno = PCI_DN(dn)->bussubno; | |
| 299 | 299 | |
| 300 | 300 | /* TODO: Parse field size properties properly. */ |
| 301 | 301 | tbl->it_size = (((unsigned long)dma_window[4] << 32) | |
| ... | ... | @@ -311,6 +311,7 @@ |
| 311 | 311 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) |
| 312 | 312 | { |
| 313 | 313 | struct device_node *dn, *pdn; |
| 314 | + struct pci_dn *pci; | |
| 314 | 315 | struct iommu_table *tbl; |
| 315 | 316 | |
| 316 | 317 | DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); |
| ... | ... | @@ -325,6 +326,7 @@ |
| 325 | 326 | */ |
| 326 | 327 | |
| 327 | 328 | dn = pci_bus_to_OF_node(bus); |
| 329 | + pci = dn->data; | |
| 328 | 330 | |
| 329 | 331 | if (!bus->self) { |
| 330 | 332 | /* Root bus */ |
| 331 | 333 | |
| 332 | 334 | |
| ... | ... | @@ -341,18 +343,18 @@ |
| 341 | 343 | * alltogether. This leaves 768MB for the window. |
| 342 | 344 | */ |
| 343 | 345 | DBG("PHB has io-hole, reserving 256MB\n"); |
| 344 | - dn->phb->dma_window_size = 3 << 28; | |
| 345 | - dn->phb->dma_window_base_cur = 1 << 28; | |
| 346 | + pci->phb->dma_window_size = 3 << 28; | |
| 347 | + pci->phb->dma_window_base_cur = 1 << 28; | |
| 346 | 348 | } else { |
| 347 | 349 | /* 1GB window by default */ |
| 348 | - dn->phb->dma_window_size = 1 << 30; | |
| 349 | - dn->phb->dma_window_base_cur = 0; | |
| 350 | + pci->phb->dma_window_size = 1 << 30; | |
| 351 | + pci->phb->dma_window_base_cur = 0; | |
| 350 | 352 | } |
| 351 | 353 | |
| 352 | 354 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 353 | 355 | |
| 354 | - iommu_table_setparms(dn->phb, dn, tbl); | |
| 355 | - dn->iommu_table = iommu_init_table(tbl); | |
| 356 | + iommu_table_setparms(pci->phb, dn, tbl); | |
| 357 | + pci->iommu_table = iommu_init_table(tbl); | |
| 356 | 358 | } else { |
| 357 | 359 | /* Do a 128MB table at root. This is used for the IDE |
| 358 | 360 | * controller on some SMP-mode POWER4 machines. It |
| 359 | 361 | |
| 360 | 362 | |
| ... | ... | @@ -363,16 +365,16 @@ |
| 363 | 365 | * Allocate at offset 128MB to avoid having to deal |
| 364 | 366 | * with ISA holes; 128MB table for IDE is plenty. |
| 365 | 367 | */ |
| 366 | - dn->phb->dma_window_size = 1 << 27; | |
| 367 | - dn->phb->dma_window_base_cur = 1 << 27; | |
| 368 | + pci->phb->dma_window_size = 1 << 27; | |
| 369 | + pci->phb->dma_window_base_cur = 1 << 27; | |
| 368 | 370 | |
| 369 | 371 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 370 | 372 | |
| 371 | - iommu_table_setparms(dn->phb, dn, tbl); | |
| 372 | - dn->iommu_table = iommu_init_table(tbl); | |
| 373 | + iommu_table_setparms(pci->phb, dn, tbl); | |
| 374 | + pci->iommu_table = iommu_init_table(tbl); | |
| 373 | 375 | |
| 374 | 376 | /* All child buses have 256MB tables */ |
| 375 | - dn->phb->dma_window_size = 1 << 28; | |
| 377 | + pci->phb->dma_window_size = 1 << 28; | |
| 376 | 378 | } |
| 377 | 379 | } else { |
| 378 | 380 | pdn = pci_bus_to_OF_node(bus->parent); |
| 379 | 381 | |
| 380 | 382 | |
| ... | ... | @@ -386,12 +388,12 @@ |
| 386 | 388 | |
| 387 | 389 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 388 | 390 | |
| 389 | - iommu_table_setparms(dn->phb, dn, tbl); | |
| 391 | + iommu_table_setparms(pci->phb, dn, tbl); | |
| 390 | 392 | |
| 391 | - dn->iommu_table = iommu_init_table(tbl); | |
| 393 | + pci->iommu_table = iommu_init_table(tbl); | |
| 392 | 394 | } else { |
| 393 | 395 | /* Lower than first child or under python, use parent table */ |
| 394 | - dn->iommu_table = pdn->iommu_table; | |
| 396 | + pci->iommu_table = PCI_DN(pdn)->iommu_table; | |
| 395 | 397 | } |
| 396 | 398 | } |
| 397 | 399 | } |
| ... | ... | @@ -401,6 +403,7 @@ |
| 401 | 403 | { |
| 402 | 404 | struct iommu_table *tbl; |
| 403 | 405 | struct device_node *dn, *pdn; |
| 406 | + struct pci_dn *ppci; | |
| 404 | 407 | unsigned int *dma_window = NULL; |
| 405 | 408 | |
| 406 | 409 | DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); |
| 407 | 410 | |
| 408 | 411 | |
| 409 | 412 | |
| 410 | 413 | |
| 411 | 414 | |
| ... | ... | @@ -419,22 +422,24 @@ |
| 419 | 422 | return; |
| 420 | 423 | } |
| 421 | 424 | |
| 422 | - if (!pdn->iommu_table) { | |
| 425 | + ppci = pdn->data; | |
| 426 | + if (!ppci->iommu_table) { | |
| 423 | 427 | /* Bussubno hasn't been copied yet. |
| 424 | 428 | * Do it now because iommu_table_setparms_lpar needs it. |
| 425 | 429 | */ |
| 426 | - pdn->bussubno = bus->number; | |
| 427 | 430 | |
| 431 | + ppci->bussubno = bus->number; | |
| 432 | + | |
| 428 | 433 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), |
| 429 | 434 | GFP_KERNEL); |
| 430 | 435 | |
| 431 | - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); | |
| 436 | + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); | |
| 432 | 437 | |
| 433 | - pdn->iommu_table = iommu_init_table(tbl); | |
| 438 | + ppci->iommu_table = iommu_init_table(tbl); | |
| 434 | 439 | } |
| 435 | 440 | |
| 436 | 441 | if (pdn != dn) |
| 437 | - dn->iommu_table = pdn->iommu_table; | |
| 442 | + PCI_DN(dn)->iommu_table = ppci->iommu_table; | |
| 438 | 443 | } |
| 439 | 444 | |
| 440 | 445 | |
| 441 | 446 | |
| ... | ... | @@ -449,11 +454,11 @@ |
| 449 | 454 | */ |
| 450 | 455 | mydn = dn = pci_device_to_OF_node(dev); |
| 451 | 456 | |
| 452 | - while (dn && dn->iommu_table == NULL) | |
| 457 | + while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) | |
| 453 | 458 | dn = dn->parent; |
| 454 | 459 | |
| 455 | - if (dn) { | |
| 456 | - mydn->iommu_table = dn->iommu_table; | |
| 460 | + if (dn && dn->data) { | |
| 461 | + PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; | |
| 457 | 462 | } else { |
| 458 | 463 | DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); |
| 459 | 464 | } |
| 460 | 465 | |
| ... | ... | @@ -463,10 +468,11 @@ |
| 463 | 468 | { |
| 464 | 469 | int err = NOTIFY_OK; |
| 465 | 470 | struct device_node *np = node; |
| 471 | + struct pci_dn *pci = np->data; | |
| 466 | 472 | |
| 467 | 473 | switch (action) { |
| 468 | 474 | case PSERIES_RECONFIG_REMOVE: |
| 469 | - if (np->iommu_table && | |
| 475 | + if (pci->iommu_table && | |
| 470 | 476 | get_property(np, "ibm,dma-window", NULL)) |
| 471 | 477 | iommu_free_table(np); |
| 472 | 478 | break; |
| ... | ... | @@ -486,6 +492,7 @@ |
| 486 | 492 | struct device_node *pdn, *dn; |
| 487 | 493 | struct iommu_table *tbl; |
| 488 | 494 | int *dma_window = NULL; |
| 495 | + struct pci_dn *pci; | |
| 489 | 496 | |
| 490 | 497 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); |
| 491 | 498 | |
| ... | ... | @@ -497,8 +504,10 @@ |
| 497 | 504 | */ |
| 498 | 505 | dn = pci_device_to_OF_node(dev); |
| 499 | 506 | |
| 500 | - for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { | |
| 501 | - dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); | |
| 507 | + for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; | |
| 508 | + pdn = pdn->parent) { | |
| 509 | + dma_window = (unsigned int *) | |
| 510 | + get_property(pdn, "ibm,dma-window", NULL); | |
| 502 | 511 | if (dma_window) |
| 503 | 512 | break; |
| 504 | 513 | } |
| 505 | 514 | |
| 506 | 515 | |
| 507 | 516 | |
| 508 | 517 | |
| ... | ... | @@ -515,20 +524,21 @@ |
| 515 | 524 | DBG("Found DMA window, allocating table\n"); |
| 516 | 525 | } |
| 517 | 526 | |
| 518 | - if (!pdn->iommu_table) { | |
| 527 | + pci = pdn->data; | |
| 528 | + if (!pci->iommu_table) { | |
| 519 | 529 | /* iommu_table_setparms_lpar needs bussubno. */ |
| 520 | - pdn->bussubno = pdn->phb->bus->number; | |
| 530 | + pci->bussubno = pci->phb->bus->number; | |
| 521 | 531 | |
| 522 | 532 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), |
| 523 | 533 | GFP_KERNEL); |
| 524 | 534 | |
| 525 | - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); | |
| 535 | + iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); | |
| 526 | 536 | |
| 527 | - pdn->iommu_table = iommu_init_table(tbl); | |
| 537 | + pci->iommu_table = iommu_init_table(tbl); | |
| 528 | 538 | } |
| 529 | 539 | |
| 530 | 540 | if (pdn != dn) |
| 531 | - dn->iommu_table = pdn->iommu_table; | |
| 541 | + PCI_DN(dn)->iommu_table = pci->iommu_table; | |
| 532 | 542 | } |
| 533 | 543 | |
| 534 | 544 | static void iommu_bus_setup_null(struct pci_bus *b) { } |
arch/ppc64/kernel/pci.c
| ... | ... | @@ -837,9 +837,11 @@ |
| 837 | 837 | * device tree. If they are then we need to scan all the |
| 838 | 838 | * functions of this slot. |
| 839 | 839 | */ |
| 840 | - for (dn = busdn->child; dn; dn = dn->sibling) | |
| 841 | - if ((dn->devfn >> 3) == (devfn >> 3)) | |
| 840 | + for (dn = busdn->child; dn; dn = dn->sibling) { | |
| 841 | + struct pci_dn *pdn = dn->data; | |
| 842 | + if (pdn && (pdn->devfn >> 3) == (devfn >> 3)) | |
| 842 | 843 | return 1; |
| 844 | + } | |
| 843 | 845 | |
| 844 | 846 | return 0; |
| 845 | 847 | } |
arch/ppc64/kernel/pci.h
| ... | ... | @@ -34,7 +34,6 @@ |
| 34 | 34 | |
| 35 | 35 | void pci_devs_phb_init(void); |
| 36 | 36 | void pci_devs_phb_init_dynamic(struct pci_controller *phb); |
| 37 | -struct device_node *fetch_dev_dn(struct pci_dev *dev); | |
| 38 | 37 | |
| 39 | 38 | /* PCI address cache management routines */ |
| 40 | 39 | void pci_addr_cache_insert_device(struct pci_dev *dev); |
arch/ppc64/kernel/pci_dn.c
| ... | ... | @@ -23,6 +23,8 @@ |
| 23 | 23 | #include <linux/pci.h> |
| 24 | 24 | #include <linux/string.h> |
| 25 | 25 | #include <linux/init.h> |
| 26 | +#include <linux/slab.h> | |
| 27 | +#include <linux/bootmem.h> | |
| 26 | 28 | |
| 27 | 29 | #include <asm/io.h> |
| 28 | 30 | #include <asm/prom.h> |
| 29 | 31 | |
| 30 | 32 | |
| 31 | 33 | |
| ... | ... | @@ -40,16 +42,26 @@ |
| 40 | 42 | struct pci_controller *phb = data; |
| 41 | 43 | int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); |
| 42 | 44 | u32 *regs; |
| 45 | + struct pci_dn *pdn; | |
| 43 | 46 | |
| 44 | - dn->phb = phb; | |
| 47 | + if (phb->is_dynamic) | |
| 48 | + pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); | |
| 49 | + else | |
| 50 | + pdn = alloc_bootmem(sizeof(*pdn)); | |
| 51 | + if (pdn == NULL) | |
| 52 | + return NULL; | |
| 53 | + memset(pdn, 0, sizeof(*pdn)); | |
| 54 | + dn->data = pdn; | |
| 55 | + pdn->node = dn; | |
| 56 | + pdn->phb = phb; | |
| 45 | 57 | regs = (u32 *)get_property(dn, "reg", NULL); |
| 46 | 58 | if (regs) { |
| 47 | 59 | /* First register entry is addr (00BBSS00) */ |
| 48 | - dn->busno = (regs[0] >> 16) & 0xff; | |
| 49 | - dn->devfn = (regs[0] >> 8) & 0xff; | |
| 60 | + pdn->busno = (regs[0] >> 16) & 0xff; | |
| 61 | + pdn->devfn = (regs[0] >> 8) & 0xff; | |
| 50 | 62 | } |
| 51 | 63 | |
| 52 | - dn->pci_ext_config_space = (type && *type == 1); | |
| 64 | + pdn->pci_ext_config_space = (type && *type == 1); | |
| 53 | 65 | return NULL; |
| 54 | 66 | } |
| 55 | 67 | |
| 56 | 68 | |
| ... | ... | @@ -112,10 +124,15 @@ |
| 112 | 124 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) |
| 113 | 125 | { |
| 114 | 126 | struct device_node * dn = (struct device_node *) phb->arch_data; |
| 127 | + struct pci_dn *pdn; | |
| 115 | 128 | |
| 116 | 129 | /* PHB nodes themselves must not match */ |
| 117 | - dn->devfn = dn->busno = -1; | |
| 118 | - dn->phb = phb; | |
| 130 | + update_dn_pci_info(dn, phb); | |
| 131 | + pdn = dn->data; | |
| 132 | + if (pdn) { | |
| 133 | + pdn->devfn = pdn->busno = -1; | |
| 134 | + pdn->phb = phb; | |
| 135 | + } | |
| 119 | 136 | |
| 120 | 137 | /* Update dn->phb ptrs for new phb and children devices */ |
| 121 | 138 | traverse_pci_devices(dn, update_dn_pci_info, phb); |
| 122 | 139 | |
| 123 | 140 | |
| ... | ... | @@ -123,14 +140,17 @@ |
| 123 | 140 | |
| 124 | 141 | /* |
| 125 | 142 | * Traversal func that looks for a <busno,devfcn> value. |
| 126 | - * If found, the device_node is returned (thus terminating the traversal). | |
| 143 | + * If found, the pci_dn is returned (thus terminating the traversal). | |
| 127 | 144 | */ |
| 128 | 145 | static void *is_devfn_node(struct device_node *dn, void *data) |
| 129 | 146 | { |
| 130 | 147 | int busno = ((unsigned long)data >> 8) & 0xff; |
| 131 | 148 | int devfn = ((unsigned long)data) & 0xff; |
| 149 | + struct pci_dn *pci = dn->data; | |
| 132 | 150 | |
| 133 | - return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL; | |
| 151 | + if (pci && (devfn == pci->devfn) && (busno == pci->busno)) | |
| 152 | + return dn; | |
| 153 | + return NULL; | |
| 134 | 154 | } |
| 135 | 155 | |
| 136 | 156 | /* |
| 137 | 157 | |
| ... | ... | @@ -149,13 +169,10 @@ |
| 149 | 169 | struct device_node *fetch_dev_dn(struct pci_dev *dev) |
| 150 | 170 | { |
| 151 | 171 | struct device_node *orig_dn = dev->sysdata; |
| 152 | - struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */ | |
| 153 | - struct device_node *phb_dn; | |
| 154 | 172 | struct device_node *dn; |
| 155 | 173 | unsigned long searchval = (dev->bus->number << 8) | dev->devfn; |
| 156 | 174 | |
| 157 | - phb_dn = phb->arch_data; | |
| 158 | - dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval); | |
| 175 | + dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); | |
| 159 | 176 | if (dn) |
| 160 | 177 | dev->sysdata = dn; |
| 161 | 178 | return dn; |
| 162 | 179 | |
| ... | ... | @@ -165,11 +182,13 @@ |
| 165 | 182 | static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) |
| 166 | 183 | { |
| 167 | 184 | struct device_node *np = node; |
| 185 | + struct pci_dn *pci; | |
| 168 | 186 | int err = NOTIFY_OK; |
| 169 | 187 | |
| 170 | 188 | switch (action) { |
| 171 | 189 | case PSERIES_RECONFIG_ADD: |
| 172 | - update_dn_pci_info(np, np->parent->phb); | |
| 190 | + pci = np->parent->data; | |
| 191 | + update_dn_pci_info(np, pci->phb); | |
| 173 | 192 | break; |
| 174 | 193 | default: |
| 175 | 194 | err = NOTIFY_DONE; |
arch/ppc64/kernel/pci_iommu.c
arch/ppc64/kernel/pmac_feature.c
| ... | ... | @@ -674,6 +674,7 @@ |
| 674 | 674 | #if 0 /* Disabled for now */ |
| 675 | 675 | u32 ufreq, freq, ucfg, cfg; |
| 676 | 676 | struct device_node *pcix_node; |
| 677 | + struct pci_dn *pdn; | |
| 677 | 678 | u8 px_bus, px_devfn; |
| 678 | 679 | struct pci_controller *px_hose; |
| 679 | 680 | |
| ... | ... | @@ -687,9 +688,10 @@ |
| 687 | 688 | printk("No PCI-X bridge found\n"); |
| 688 | 689 | return; |
| 689 | 690 | } |
| 690 | - px_hose = pcix_node->phb; | |
| 691 | - px_bus = pcix_node->busno; | |
| 692 | - px_devfn = pcix_node->devfn; | |
| 691 | + pdn = pcix_node->data; | |
| 692 | + px_hose = pdn->phb; | |
| 693 | + px_bus = pdn->busno; | |
| 694 | + px_devfn = pdn->devfn; | |
| 693 | 695 | |
| 694 | 696 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); |
| 695 | 697 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); |
arch/ppc64/kernel/pmac_pci.c
| ... | ... | @@ -242,7 +242,7 @@ |
| 242 | 242 | else |
| 243 | 243 | busdn = hose->arch_data; |
| 244 | 244 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 245 | - if (dn->devfn == devfn) | |
| 245 | + if (dn->data && PCI_DN(dn)->devfn == devfn) | |
| 246 | 246 | break; |
| 247 | 247 | if (dn == NULL) |
| 248 | 248 | return -1; |
| 249 | 249 | |
| ... | ... | @@ -746,9 +746,9 @@ |
| 746 | 746 | */ |
| 747 | 747 | if (u3_agp) { |
| 748 | 748 | struct device_node *np = u3_agp->arch_data; |
| 749 | - np->busno = 0xf0; | |
| 749 | + PCI_DN(np)->busno = 0xf0; | |
| 750 | 750 | for (np = np->child; np; np = np->sibling) |
| 751 | - np->busno = 0xf0; | |
| 751 | + PCI_DN(np)->busno = 0xf0; | |
| 752 | 752 | } |
| 753 | 753 | |
| 754 | 754 | pmac_check_ht_link(); |
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/rtas_pci.c
| ... | ... | @@ -48,7 +48,7 @@ |
| 48 | 48 | static int ibm_read_pci_config; |
| 49 | 49 | static int ibm_write_pci_config; |
| 50 | 50 | |
| 51 | -static int config_access_valid(struct device_node *dn, int where) | |
| 51 | +static int config_access_valid(struct pci_dn *dn, int where) | |
| 52 | 52 | { |
| 53 | 53 | if (where < 256) |
| 54 | 54 | return 1; |
| 55 | 55 | |
| 56 | 56 | |
| 57 | 57 | |
| ... | ... | @@ -78,15 +78,17 @@ |
| 78 | 78 | int returnval = -1; |
| 79 | 79 | unsigned long buid, addr; |
| 80 | 80 | int ret; |
| 81 | + struct pci_dn *pdn; | |
| 81 | 82 | |
| 82 | - if (!dn) | |
| 83 | + if (!dn || !dn->data) | |
| 83 | 84 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 84 | - if (!config_access_valid(dn, where)) | |
| 85 | + pdn = dn->data; | |
| 86 | + if (!config_access_valid(pdn, where)) | |
| 85 | 87 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 86 | 88 | |
| 87 | - addr = ((where & 0xf00) << 20) | (dn->busno << 16) | | |
| 88 | - (dn->devfn << 8) | (where & 0xff); | |
| 89 | - buid = dn->phb->buid; | |
| 89 | + addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | | |
| 90 | + (pdn->devfn << 8) | (where & 0xff); | |
| 91 | + buid = pdn->phb->buid; | |
| 90 | 92 | if (buid) { |
| 91 | 93 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, |
| 92 | 94 | addr, buid >> 32, buid & 0xffffffff, size); |
| ... | ... | @@ -98,8 +100,8 @@ |
| 98 | 100 | if (ret) |
| 99 | 101 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 100 | 102 | |
| 101 | - if (returnval == EEH_IO_ERROR_VALUE(size) | |
| 102 | - && eeh_dn_check_failure (dn, NULL)) | |
| 103 | + if (returnval == EEH_IO_ERROR_VALUE(size) && | |
| 104 | + eeh_dn_check_failure (dn, NULL)) | |
| 103 | 105 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 104 | 106 | |
| 105 | 107 | return PCIBIOS_SUCCESSFUL; |
| 106 | 108 | |
| 107 | 109 | |
| 108 | 110 | |
| 109 | 111 | |
| 110 | 112 | |
| 111 | 113 | |
| ... | ... | @@ -118,24 +120,28 @@ |
| 118 | 120 | |
| 119 | 121 | /* Search only direct children of the bus */ |
| 120 | 122 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 121 | - if (dn->devfn == devfn && of_device_available(dn)) | |
| 123 | + if (dn->data && PCI_DN(dn)->devfn == devfn | |
| 124 | + && of_device_available(dn)) | |
| 122 | 125 | return rtas_read_config(dn, where, size, val); |
| 126 | + | |
| 123 | 127 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 124 | 128 | } |
| 125 | 129 | |
| 126 | -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) | |
| 130 | +int rtas_write_config(struct device_node *dn, int where, int size, u32 val) | |
| 127 | 131 | { |
| 128 | 132 | unsigned long buid, addr; |
| 129 | 133 | int ret; |
| 134 | + struct pci_dn *pdn; | |
| 130 | 135 | |
| 131 | - if (!dn) | |
| 136 | + if (!dn || !dn->data) | |
| 132 | 137 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 133 | - if (!config_access_valid(dn, where)) | |
| 138 | + pdn = dn->data; | |
| 139 | + if (!config_access_valid(pdn, where)) | |
| 134 | 140 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 135 | 141 | |
| 136 | - addr = ((where & 0xf00) << 20) | (dn->busno << 16) | | |
| 137 | - (dn->devfn << 8) | (where & 0xff); | |
| 138 | - buid = dn->phb->buid; | |
| 142 | + addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | | |
| 143 | + (pdn->devfn << 8) | (where & 0xff); | |
| 144 | + buid = pdn->phb->buid; | |
| 139 | 145 | if (buid) { |
| 140 | 146 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); |
| 141 | 147 | } else { |
| ... | ... | @@ -161,7 +167,8 @@ |
| 161 | 167 | |
| 162 | 168 | /* Search only direct children of the bus */ |
| 163 | 169 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 164 | - if (dn->devfn == devfn && of_device_available(dn)) | |
| 170 | + if (dn->data && PCI_DN(dn)->devfn == devfn | |
| 171 | + && of_device_available(dn)) | |
| 165 | 172 | return rtas_write_config(dn, where, size, val); |
| 166 | 173 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 167 | 174 | } |
arch/ppc64/kernel/sys_ppc32.c
| ... | ... | @@ -747,8 +747,8 @@ |
| 747 | 747 | if (bus == NULL || bus->sysdata == NULL) |
| 748 | 748 | return -ENODEV; |
| 749 | 749 | |
| 750 | - hose_node = (struct device_node *)bus->sysdata; | |
| 751 | - hose = hose_node->phb; | |
| 750 | + hose_node = bus->sysdata; | |
| 751 | + hose = PCI_DN(hose_node)->phb; | |
| 752 | 752 | |
| 753 | 753 | switch (which) { |
| 754 | 754 | case IOBASE_BRIDGE_NUMBER: |
arch/ppc64/kernel/u3_iommu.c
| ... | ... | @@ -276,7 +276,7 @@ |
| 276 | 276 | dn = pci_device_to_OF_node(dev); |
| 277 | 277 | |
| 278 | 278 | if (dn) |
| 279 | - dn->iommu_table = &iommu_table_u3; | |
| 279 | + PCI_DN(dn)->iommu_table = &iommu_table_u3; | |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | 282 | static void iommu_bus_setup_u3(struct pci_bus *bus) |
| ... | ... | @@ -291,7 +291,7 @@ |
| 291 | 291 | dn = pci_bus_to_OF_node(bus); |
| 292 | 292 | |
| 293 | 293 | if (dn) |
| 294 | - dn->iommu_table = &iommu_table_u3; | |
| 294 | + PCI_DN(dn)->iommu_table = &iommu_table_u3; | |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | 297 | static void iommu_dev_setup_null(struct pci_dev *dev) { } |
drivers/pci/hotplug/rpadlpar_core.c
| ... | ... | @@ -134,7 +134,8 @@ |
| 134 | 134 | static int pci_add_secondary_bus(struct device_node *dn, |
| 135 | 135 | struct pci_dev *bridge_dev) |
| 136 | 136 | { |
| 137 | - struct pci_controller *hose = dn->phb; | |
| 137 | + struct pci_dn *pdn = dn->data; | |
| 138 | + struct pci_controller *hose = pdn->phb; | |
| 138 | 139 | struct pci_bus *child; |
| 139 | 140 | u8 sec_busno; |
| 140 | 141 | |
| ... | ... | @@ -159,7 +160,7 @@ |
| 159 | 160 | if (hose->last_busno < child->number) |
| 160 | 161 | hose->last_busno = child->number; |
| 161 | 162 | |
| 162 | - dn->bussubno = child->number; | |
| 163 | + pdn->bussubno = child->number; | |
| 163 | 164 | |
| 164 | 165 | /* ioremap() for child bus, which may or may not succeed */ |
| 165 | 166 | remap_bus_range(child); |
| 166 | 167 | |
| ... | ... | @@ -183,11 +184,12 @@ |
| 183 | 184 | |
| 184 | 185 | static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) |
| 185 | 186 | { |
| 186 | - struct pci_controller *hose = dn->phb; | |
| 187 | + struct pci_dn *pdn = dn->data; | |
| 188 | + struct pci_controller *hose = pdn->phb; | |
| 187 | 189 | struct pci_dev *dev = NULL; |
| 188 | 190 | |
| 189 | 191 | /* Scan phb bus for EADS device, adding new one to bus->devices */ |
| 190 | - if (!pci_scan_single_device(hose->bus, dn->devfn)) { | |
| 192 | + if (!pci_scan_single_device(hose->bus, pdn->devfn)) { | |
| 191 | 193 | printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__); |
| 192 | 194 | return NULL; |
| 193 | 195 | } |
| ... | ... | @@ -269,6 +271,7 @@ |
| 269 | 271 | static int dlpar_remove_phb(char *drc_name, struct device_node *dn) |
| 270 | 272 | { |
| 271 | 273 | struct slot *slot; |
| 274 | + struct pci_dn *pdn; | |
| 272 | 275 | int rc = 0; |
| 273 | 276 | |
| 274 | 277 | if (!rpaphp_find_pci_bus(dn)) |
| 275 | 278 | |
| ... | ... | @@ -285,12 +288,13 @@ |
| 285 | 288 | } |
| 286 | 289 | } |
| 287 | 290 | |
| 288 | - BUG_ON(!dn->phb); | |
| 289 | - rc = dlpar_remove_root_bus(dn->phb); | |
| 291 | + pdn = dn->data; | |
| 292 | + BUG_ON(!pdn || !pdn->phb); | |
| 293 | + rc = dlpar_remove_root_bus(pdn->phb); | |
| 290 | 294 | if (rc < 0) |
| 291 | 295 | return rc; |
| 292 | 296 | |
| 293 | - dn->phb = NULL; | |
| 297 | + pdn->phb = NULL; | |
| 294 | 298 | |
| 295 | 299 | return 0; |
| 296 | 300 | } |
| ... | ... | @@ -299,7 +303,7 @@ |
| 299 | 303 | { |
| 300 | 304 | struct pci_controller *phb; |
| 301 | 305 | |
| 302 | - if (dn->phb) { | |
| 306 | + if (PCI_DN(dn)->phb) { | |
| 303 | 307 | /* PHB already exists */ |
| 304 | 308 | return -EINVAL; |
| 305 | 309 | } |
drivers/pci/hotplug/rpaphp_pci.c
| ... | ... | @@ -51,10 +51,12 @@ |
| 51 | 51 | |
| 52 | 52 | struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) |
| 53 | 53 | { |
| 54 | - if (!dn->phb || !dn->phb->bus) | |
| 54 | + struct pci_dn *pdn = dn->data; | |
| 55 | + | |
| 56 | + if (!pdn || !pdn->phb || !pdn->phb->bus) | |
| 55 | 57 | return NULL; |
| 56 | 58 | |
| 57 | - return find_bus_among_children(dn->phb->bus, dn); | |
| 59 | + return find_bus_among_children(pdn->phb->bus, dn); | |
| 58 | 60 | } |
| 59 | 61 | EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); |
| 60 | 62 | |
| ... | ... | @@ -229,7 +231,7 @@ |
| 229 | 231 | if (!dn || !dn->child) |
| 230 | 232 | return NULL; |
| 231 | 233 | |
| 232 | - slotno = PCI_SLOT(dn->child->devfn); | |
| 234 | + slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | |
| 233 | 235 | |
| 234 | 236 | /* pci_scan_slot should find all children */ |
| 235 | 237 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
drivers/video/offb.c
include/asm-ppc64/pci-bridge.h
| ... | ... | @@ -48,19 +48,52 @@ |
| 48 | 48 | unsigned long dma_window_size; |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | +/* | |
| 52 | + * PCI stuff, for nodes representing PCI devices, pointed to | |
| 53 | + * by device_node->data. | |
| 54 | + */ | |
| 55 | +struct pci_controller; | |
| 56 | +struct iommu_table; | |
| 57 | + | |
| 58 | +struct pci_dn { | |
| 59 | + int busno; /* for pci devices */ | |
| 60 | + int bussubno; /* for pci devices */ | |
| 61 | + int devfn; /* for pci devices */ | |
| 62 | + int eeh_mode; /* See eeh.h for possible EEH_MODEs */ | |
| 63 | + int eeh_config_addr; | |
| 64 | + int eeh_capable; /* from firmware */ | |
| 65 | + int eeh_check_count; /* # times driver ignored error */ | |
| 66 | + int eeh_freeze_count; /* # times this device froze up. */ | |
| 67 | + int eeh_is_bridge; /* device is pci-to-pci bridge */ | |
| 68 | + | |
| 69 | + int pci_ext_config_space; /* for pci devices */ | |
| 70 | + struct pci_controller *phb; /* for pci devices */ | |
| 71 | + struct iommu_table *iommu_table; /* for phb's or bridges */ | |
| 72 | + struct pci_dev *pcidev; /* back-pointer to the pci device */ | |
| 73 | + struct device_node *node; /* back-pointer to the device_node */ | |
| 74 | + u32 config_space[16]; /* saved PCI config space */ | |
| 75 | +}; | |
| 76 | + | |
| 77 | +/* Get the pointer to a device_node's pci_dn */ | |
| 78 | +#define PCI_DN(dn) ((struct pci_dn *) (dn)->data) | |
| 79 | + | |
| 51 | 80 | struct device_node *fetch_dev_dn(struct pci_dev *dev); |
| 52 | 81 | |
| 53 | -/* Get a device_node from a pci_dev. This code must be fast except in the case | |
| 54 | - * where the sysdata is incorrect and needs to be fixed up (hopefully just once) | |
| 82 | +/* Get a device_node from a pci_dev. This code must be fast except | |
| 83 | + * in the case where the sysdata is incorrect and needs to be fixed | |
| 84 | + * up (this will only happen once). | |
| 85 | + * In this case the sysdata will have been inherited from a PCI host | |
| 86 | + * bridge or a PCI-PCI bridge further up the tree, so it will point | |
| 87 | + * to a valid struct pci_dn, just not the one we want. | |
| 55 | 88 | */ |
| 56 | 89 | static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) |
| 57 | 90 | { |
| 58 | 91 | struct device_node *dn = dev->sysdata; |
| 92 | + struct pci_dn *pdn = dn->data; | |
| 59 | 93 | |
| 60 | - if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) | |
| 94 | + if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number) | |
| 61 | 95 | return dn; /* fast path. sysdata is good */ |
| 62 | - else | |
| 63 | - return fetch_dev_dn(dev); | |
| 96 | + return fetch_dev_dn(dev); | |
| 64 | 97 | } |
| 65 | 98 | |
| 66 | 99 | static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) |
| ... | ... | @@ -83,7 +116,7 @@ |
| 83 | 116 | struct device_node *busdn = bus->sysdata; |
| 84 | 117 | |
| 85 | 118 | BUG_ON(busdn == NULL); |
| 86 | - return busdn->phb; | |
| 119 | + return PCI_DN(busdn)->phb; | |
| 87 | 120 | } |
| 88 | 121 | |
| 89 | 122 | #endif |
include/asm-ppc64/prom.h
| ... | ... | @@ -116,14 +116,6 @@ |
| 116 | 116 | struct property *next; |
| 117 | 117 | }; |
| 118 | 118 | |
| 119 | -/* NOTE: the device_node contains PCI specific info for pci devices. | |
| 120 | - * This perhaps could be hung off the device_node with another struct, | |
| 121 | - * but for now it is directly in the node. The phb ptr is a good | |
| 122 | - * indication of a real PCI node. Other nodes leave these fields zeroed. | |
| 123 | - */ | |
| 124 | -struct pci_controller; | |
| 125 | -struct iommu_table; | |
| 126 | - | |
| 127 | 119 | struct device_node { |
| 128 | 120 | char *name; |
| 129 | 121 | char *type; |
| ... | ... | @@ -135,16 +127,6 @@ |
| 135 | 127 | struct interrupt_info *intrs; |
| 136 | 128 | char *full_name; |
| 137 | 129 | |
| 138 | - /* PCI stuff probably doesn't belong here */ | |
| 139 | - int busno; /* for pci devices */ | |
| 140 | - int bussubno; /* for pci devices */ | |
| 141 | - int devfn; /* for pci devices */ | |
| 142 | - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ | |
| 143 | - int eeh_config_addr; | |
| 144 | - int pci_ext_config_space; /* for pci devices */ | |
| 145 | - struct pci_controller *phb; /* for pci devices */ | |
| 146 | - struct iommu_table *iommu_table; /* for phb's or bridges */ | |
| 147 | - | |
| 148 | 130 | struct property *properties; |
| 149 | 131 | struct device_node *parent; |
| 150 | 132 | struct device_node *child; |
| ... | ... | @@ -154,6 +136,7 @@ |
| 154 | 136 | struct proc_dir_entry *pde; /* this node's proc directory */ |
| 155 | 137 | struct kref kref; |
| 156 | 138 | unsigned long _flags; |
| 139 | + void *data; | |
| 157 | 140 | }; |
| 158 | 141 | |
| 159 | 142 | extern struct device_node *of_chosen; |