1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * PCI Dynamic LPAR, PCI Hot Plug and PCI EEH recovery code 4 * for RPA-compliant PPC64 platform. 5 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com> 6 * Copyright (C) 2005 International Business Machines 7 * 8 * Updates, 2005, John Rose <johnrose@austin.ibm.com> 9 * Updates, 2005, Linas Vepstas <linas@austin.ibm.com> 10 */ 11 12 #include <linux/pci.h> 13 #include <linux/export.h> 14 #include <linux/node.h> 15 #include <asm/pci-bridge.h> 16 #include <asm/ppc-pci.h> 17 #include <asm/firmware.h> 18 #include <asm/eeh.h> 19 20 #include "pseries.h" 21 22 struct pci_controller *init_phb_dynamic(struct device_node *dn) 23 { 24 struct pci_controller *phb; 25 int nid; 26 27 pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn); 28 29 nid = of_node_to_nid(dn); 30 if (likely((nid) >= 0)) { 31 if (!node_online(nid)) { 32 if (__register_one_node(nid)) { 33 pr_err("PCI: Failed to register node %d\n", nid); 34 } else { 35 update_numa_distance(dn); 36 node_set_online(nid); 37 } 38 } 39 } 40 41 phb = pcibios_alloc_controller(dn); 42 if (!phb) 43 return NULL; 44 rtas_setup_phb(phb); 45 pci_process_bridge_OF_ranges(phb, dn, 0); 46 phb->controller_ops = pseries_pci_controller_ops; 47 48 pci_devs_phb_init_dynamic(phb); 49 50 pseries_msi_allocate_domains(phb); 51 52 ppc_iommu_register_device(phb); 53 54 /* Create EEH devices for the PHB */ 55 eeh_phb_pe_create(phb); 56 57 if (dn->child) 58 pseries_eeh_init_edev_recursive(PCI_DN(dn)); 59 60 pcibios_scan_phb(phb); 61 pcibios_finish_adding_to_bus(phb->bus); 62 63 return phb; 64 } 65 EXPORT_SYMBOL_GPL(init_phb_dynamic); 66 67 /* RPA-specific bits for removing PHBs */ 68 int remove_phb_dynamic(struct pci_controller *phb) 69 { 70 struct pci_bus *b = phb->bus; 71 struct pci_host_bridge *host_bridge = to_pci_host_bridge(b->bridge); 72 struct resource *res; 73 int rc, i; 74 75 pr_debug("PCI: Removing PHB %04x:%02x...\n", 76 pci_domain_nr(b), b->number); 77 78 /* We cannot to remove a root bus that has children */ 79 if (!(list_empty(&b->children) && list_empty(&b->devices))) 80 return -EBUSY; 81 82 /* We -know- there aren't any child devices anymore at this stage 83 * and thus, we can safely unmap the IO space as it's not in use 84 */ 85 res = &phb->io_resource; 86 if (res->flags & IORESOURCE_IO) { 87 rc = pcibios_unmap_io_space(b); 88 if (rc) { 89 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", 90 __func__, b->name); 91 return 1; 92 } 93 } 94 95 ppc_iommu_unregister_device(phb); 96 97 pseries_msi_free_domains(phb); 98 99 /* Keep a reference so phb isn't freed yet */ 100 get_device(&host_bridge->dev); 101 102 /* Remove the PCI bus and unregister the bridge device from sysfs */ 103 phb->bus = NULL; 104 pci_remove_bus(b); 105 host_bridge->bus = NULL; 106 device_unregister(&host_bridge->dev); 107 108 /* Now release the IO resource */ 109 if (res->flags & IORESOURCE_IO) 110 release_resource(res); 111 112 /* Release memory resources */ 113 for (i = 0; i < 3; ++i) { 114 res = &phb->mem_resources[i]; 115 if (!(res->flags & IORESOURCE_MEM)) 116 continue; 117 release_resource(res); 118 } 119 120 /* 121 * The pci_controller data structure is freed by 122 * the pcibios_free_controller_deferred() callback; 123 * see pseries_root_bridge_prepare(). 124 */ 125 put_device(&host_bridge->dev); 126 127 return 0; 128 } 129 EXPORT_SYMBOL_GPL(remove_phb_dynamic); 130