Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM/PCI: Convert PCI scan API to pci_scan_root_bus_bridge()

The introduction of pci_scan_root_bus_bridge() provides a PCI core API to
scan a PCI root bus backed by an already initialized struct pci_host_bridge
object, which simplifies the bus scan interface and makes the PCI scan root
bus interface easier to generalize as members are added to the struct
pci_host_bridge.

Convert ARM bios32 code to pci_scan_root_bus_bridge() to improve the PCI
root bus scanning interface.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
[bhelgaas: fold in warning fix from Arnd Bergmann <arnd@arndb.de>:
http://lkml.kernel.org/r/20170621215323.3921382-1-arnd@arndb.de]
[bhelgaas: set bridge->ops for mv78xx0]
[bhelgaas: fold in fixes from Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>:
http://lkml.kernel.org/r/20170701135457.GB8977@red-moon]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Andrew Lunn <andrew@lunn.ch>

authored by

Lorenzo Pieralisi and committed by
Bjorn Helgaas
97ad2bdc cea9bc0b

+91 -46
+2 -1
arch/arm/include/asm/mach/pci.h
··· 16 16 struct pci_sys_data; 17 17 struct pci_ops; 18 18 struct pci_bus; 19 + struct pci_host_bridge; 19 20 struct device; 20 21 21 22 struct hw_pci { ··· 26 25 unsigned int io_optional:1; 27 26 void **private_data; 28 27 int (*setup)(int nr, struct pci_sys_data *); 29 - struct pci_bus *(*scan)(int nr, struct pci_sys_data *); 28 + int (*scan)(int nr, struct pci_host_bridge *); 30 29 void (*preinit)(void); 31 30 void (*postinit)(void); 32 31 u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
+25 -14
arch/arm/kernel/bios32.c
··· 458 458 int nr, busnr; 459 459 460 460 for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { 461 - sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL); 462 - if (WARN(!sys, "PCI: unable to allocate sys data!")) 461 + struct pci_host_bridge *bridge; 462 + 463 + bridge = pci_alloc_host_bridge(sizeof(struct pci_sys_data)); 464 + if (WARN(!bridge, "PCI: unable to allocate bridge!")) 463 465 break; 466 + 467 + sys = pci_host_bridge_priv(bridge); 464 468 465 469 sys->busnr = busnr; 466 470 sys->swizzle = hw->swizzle; ··· 477 473 ret = hw->setup(nr, sys); 478 474 479 475 if (ret > 0) { 480 - struct pci_host_bridge *host_bridge; 481 476 482 477 ret = pcibios_init_resource(nr, sys, hw->io_optional); 483 478 if (ret) { ··· 485 482 } 486 483 487 484 if (hw->scan) 488 - sys->bus = hw->scan(nr, sys); 489 - else 490 - sys->bus = pci_scan_root_bus_msi(parent, 491 - sys->busnr, hw->ops, sys, 492 - &sys->resources, hw->msi_ctrl); 485 + ret = hw->scan(nr, bridge); 486 + else { 487 + list_splice_init(&sys->resources, 488 + &bridge->windows); 489 + bridge->dev.parent = parent; 490 + bridge->sysdata = sys; 491 + bridge->busnr = sys->busnr; 492 + bridge->ops = hw->ops; 493 + bridge->msi = hw->msi_ctrl; 494 + bridge->align_resource = 495 + hw->align_resource; 493 496 494 - if (WARN(!sys->bus, "PCI: unable to scan bus!")) { 495 - kfree(sys); 497 + ret = pci_scan_root_bus_bridge(bridge); 498 + } 499 + 500 + if (WARN(ret < 0, "PCI: unable to scan bus!")) { 501 + pci_free_host_bridge(bridge); 496 502 break; 497 503 } 504 + 505 + sys->bus = bridge->bus; 498 506 499 507 busnr = sys->bus->busn_res.end + 1; 500 508 501 509 list_add(&sys->node, head); 502 - 503 - host_bridge = pci_find_host_bridge(sys->bus); 504 - host_bridge->align_resource = hw->align_resource; 505 510 } else { 506 - kfree(sys); 511 + pci_free_host_bridge(bridge); 507 512 if (ret < 0) 508 513 break; 509 514 }
+12 -5
arch/arm/mach-dove/pcie.c
··· 152 152 } 153 153 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); 154 154 155 - static struct pci_bus __init * 156 - dove_pcie_scan_bus(int nr, struct pci_sys_data *sys) 155 + static int __init 156 + dove_pcie_scan_bus(int nr, struct pci_host_bridge *bridge) 157 157 { 158 + struct pci_sys_data *sys = pci_host_bridge_priv(bridge); 159 + 158 160 if (nr >= num_pcie_ports) { 159 161 BUG(); 160 - return NULL; 162 + return -EINVAL; 161 163 } 162 164 163 - return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, 164 - &sys->resources); 165 + list_splice_init(&sys->resources, &bridge->windows); 166 + bridge->dev.parent = NULL; 167 + bridge->sysdata = sys; 168 + bridge->busnr = sys->busnr; 169 + bridge->ops = &pcie_ops; 170 + 171 + return pci_scan_root_bus_bridge(bridge); 165 172 } 166 173 167 174 static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+20 -11
arch/arm/mach-iop13xx/pci.c
··· 504 504 505 505 /* Scan an IOP13XX PCI bus. nr selects which ATU we use. 506 506 */ 507 - struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys) 507 + int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge) 508 508 { 509 - int which_atu; 510 - struct pci_bus *bus = NULL; 509 + int which_atu, ret; 510 + struct pci_sys_data *sys = pci_host_bridge_priv(bridge); 511 511 512 512 switch (init_atu) { 513 513 case IOP13XX_INIT_ATU_ATUX: ··· 525 525 526 526 if (!which_atu) { 527 527 BUG(); 528 - return NULL; 528 + return -ENODEV; 529 529 } 530 + 531 + list_splice_init(&sys->resources, &bridge->windows); 532 + bridge->dev.parent = NULL; 533 + bridge->sysdata = sys; 534 + bridge->busnr = sys->busnr; 530 535 531 536 switch (which_atu) { 532 537 case IOP13XX_INIT_ATU_ATUX: ··· 540 535 while(time_before(jiffies, atux_trhfa_timeout)) 541 536 udelay(100); 542 537 543 - bus = pci_bus_atux = pci_scan_root_bus(NULL, sys->busnr, 544 - &iop13xx_atux_ops, 545 - sys, &sys->resources); 538 + bridge->ops = &iop13xx_atux_ops; 539 + ret = pci_scan_root_bus_bridge(bridge); 540 + if (!ret) 541 + pci_bus_atux = bridge->bus; 546 542 break; 547 543 case IOP13XX_INIT_ATU_ATUE: 548 - bus = pci_bus_atue = pci_scan_root_bus(NULL, sys->busnr, 549 - &iop13xx_atue_ops, 550 - sys, &sys->resources); 544 + bridge->ops = &iop13xx_atue_ops; 545 + ret = pci_scan_root_bus_bridge(bridge); 546 + if (!ret) 547 + pci_bus_atue = bridge->bus; 551 548 break; 549 + default: 550 + ret = -EINVAL; 552 551 } 553 552 554 - return bus; 553 + return ret; 555 554 } 556 555 557 556 /* This function is called from iop13xx_pci_init() after assigning valid
+2 -1
arch/arm/mach-iop13xx/pci.h
··· 11 11 extern size_t iop13xx_atux_mem_size; 12 12 13 13 struct pci_sys_data; 14 + struct pci_host_bridge; 14 15 struct hw_pci; 15 16 int iop13xx_pci_setup(int nr, struct pci_sys_data *sys); 16 - struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *); 17 + int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge); 17 18 void iop13xx_atu_select(struct hw_pci *plat_pci); 18 19 void iop13xx_pci_init(void); 19 20 void iop13xx_map_pci_memory(void);
+11 -5
arch/arm/mach-mv78xx0/pcie.c
··· 194 194 } 195 195 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); 196 196 197 - static struct pci_bus __init * 198 - mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) 197 + static int __init mv78xx0_pcie_scan_bus(int nr, struct pci_host_bridge *bridge) 199 198 { 199 + struct pci_sys_data *sys = pci_host_bridge_priv(bridge); 200 + 200 201 if (nr >= num_pcie_ports) { 201 202 BUG(); 202 - return NULL; 203 + return -EINVAL; 203 204 } 204 205 205 - return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, 206 - &sys->resources); 206 + list_splice_init(&sys->resources, &bridge->windows); 207 + bridge->dev.parent = NULL; 208 + bridge->sysdata = sys; 209 + bridge->busnr = sys->busnr; 210 + bridge->ops = &pcie_ops; 211 + 212 + return pci_scan_root_bus_bridge(bridge); 207 213 } 208 214 209 215 static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot,
+2 -1
arch/arm/mach-orion5x/common.h
··· 54 54 * PCIe/PCI functions. 55 55 */ 56 56 struct pci_bus; 57 + struct pci_host_bridge; 57 58 struct pci_sys_data; 58 59 struct pci_dev; 59 60 ··· 62 61 void orion5x_pci_disable(void); 63 62 void orion5x_pci_set_cardbus_mode(void); 64 63 int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); 65 - struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); 64 + int orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge); 66 65 int orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); 67 66 68 67 struct tag;
+17 -8
arch/arm/mach-orion5x/pci.c
··· 555 555 return 0; 556 556 } 557 557 558 - struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys) 558 + int __init orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge) 559 559 { 560 - if (nr == 0) 561 - return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, 562 - &sys->resources); 560 + struct pci_sys_data *sys = pci_host_bridge_priv(bridge); 563 561 564 - if (nr == 1 && !orion5x_pci_disabled) 565 - return pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys, 566 - &sys->resources); 562 + list_splice_init(&sys->resources, &bridge->windows); 563 + bridge->dev.parent = NULL; 564 + bridge->sysdata = sys; 565 + bridge->busnr = sys->busnr; 566 + 567 + if (nr == 0) { 568 + bridge->ops = &pcie_ops; 569 + return pci_scan_root_bus_bridge(bridge); 570 + } 571 + 572 + if (nr == 1 && !orion5x_pci_disabled) { 573 + bridge->ops = &pci_ops; 574 + return pci_scan_root_bus_bridge(bridge); 575 + } 567 576 568 577 BUG(); 569 - return NULL; 578 + return -ENODEV; 570 579 } 571 580 572 581 int __init orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)