1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. 4 * <benh@kernel.crashing.org> 5 * and Arnd Bergmann, IBM Corp. 6 */ 7 8 #undef DEBUG 9 10 #include <linux/string.h> 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/export.h> 14 #include <linux/mod_devicetable.h> 15 #include <linux/pci.h> 16 #include <linux/platform_device.h> 17 #include <linux/atomic.h> 18 19 #include <asm/errno.h> 20 #include <asm/topology.h> 21 #include <asm/pci-bridge.h> 22 #include <asm/ppc-pci.h> 23 #include <asm/eeh.h> 24 25 #ifdef CONFIG_PPC_OF_PLATFORM_PCI 26 27 /* The probing of PCI controllers from of_platform is currently 28 * 64 bits only, mostly due to gratuitous differences between 29 * the 32 and 64 bits PCI code on PowerPC and the 32 bits one 30 * lacking some bits needed here. 31 */ 32 33 static int of_pci_phb_probe(struct platform_device *dev) 34 { 35 struct pci_controller *phb; 36 37 /* Check if we can do that ... */ 38 if (ppc_md.pci_setup_phb == NULL) 39 return -ENODEV; 40 41 pr_info("Setting up PCI bus %pOF\n", dev->dev.of_node); 42 43 /* Alloc and setup PHB data structure */ 44 phb = pcibios_alloc_controller(dev->dev.of_node); 45 if (!phb) 46 return -ENODEV; 47 48 /* Setup parent in sysfs */ 49 phb->parent = &dev->dev; 50 51 /* Setup the PHB using arch provided callback */ 52 if (ppc_md.pci_setup_phb(phb)) { 53 pcibios_free_controller(phb); 54 return -ENODEV; 55 } 56 57 /* Process "ranges" property */ 58 pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); 59 60 /* Init pci_dn data structures */ 61 pci_devs_phb_init_dynamic(phb); 62 63 /* Create EEH PE for the PHB */ 64 eeh_phb_pe_create(phb); 65 66 /* Scan the bus */ 67 pcibios_scan_phb(phb); 68 if (phb->bus == NULL) 69 return -ENXIO; 70 71 /* Claim resources. This might need some rework as well depending 72 * whether we are doing probe-only or not, like assigning unassigned 73 * resources etc... 74 */ 75 pcibios_claim_one_bus(phb->bus); 76 77 /* Add probed PCI devices to the device model */ 78 pci_bus_add_devices(phb->bus); 79 80 return 0; 81 } 82 83 static const struct of_device_id of_pci_phb_ids[] = { 84 { .type = "pci", }, 85 { .type = "pcix", }, 86 { .type = "pcie", }, 87 { .type = "pciex", }, 88 { .type = "ht", }, 89 {} 90 }; 91 92 static struct platform_driver of_pci_phb_driver = { 93 .probe = of_pci_phb_probe, 94 .driver = { 95 .name = "of-pci", 96 .of_match_table = of_pci_phb_ids, 97 }, 98 }; 99 100 builtin_platform_driver(of_pci_phb_driver); 101 102 #endif /* CONFIG_PPC_OF_PLATFORM_PCI */ 103