Path: blob/master/arch/powerpc/platforms/pseries/pci_dlpar.c
26481 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* PCI Dynamic LPAR, PCI Hot Plug and PCI EEH recovery code3* for RPA-compliant PPC64 platform.4* Copyright (C) 2003 Linda Xie <[email protected]>5* Copyright (C) 2005 International Business Machines6*7* Updates, 2005, John Rose <[email protected]>8* Updates, 2005, Linas Vepstas <[email protected]>9*/1011#include <linux/pci.h>12#include <linux/export.h>13#include <linux/node.h>14#include <asm/pci-bridge.h>15#include <asm/ppc-pci.h>16#include <asm/firmware.h>17#include <asm/eeh.h>1819#include "pseries.h"2021struct pci_controller *init_phb_dynamic(struct device_node *dn)22{23struct pci_controller *phb;24int nid;2526pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn);2728nid = of_node_to_nid(dn);29if (likely((nid) >= 0)) {30if (!node_online(nid)) {31if (register_one_node(nid)) {32pr_err("PCI: Failed to register node %d\n", nid);33} else {34update_numa_distance(dn);35node_set_online(nid);36}37}38}3940phb = pcibios_alloc_controller(dn);41if (!phb)42return NULL;43rtas_setup_phb(phb);44pci_process_bridge_OF_ranges(phb, dn, 0);45phb->controller_ops = pseries_pci_controller_ops;4647pci_devs_phb_init_dynamic(phb);4849pseries_msi_allocate_domains(phb);5051ppc_iommu_register_device(phb);5253/* Create EEH devices for the PHB */54eeh_phb_pe_create(phb);5556if (dn->child)57pseries_eeh_init_edev_recursive(PCI_DN(dn));5859pcibios_scan_phb(phb);60pcibios_finish_adding_to_bus(phb->bus);6162return phb;63}64EXPORT_SYMBOL_GPL(init_phb_dynamic);6566/* RPA-specific bits for removing PHBs */67int remove_phb_dynamic(struct pci_controller *phb)68{69struct pci_bus *b = phb->bus;70struct pci_host_bridge *host_bridge = to_pci_host_bridge(b->bridge);71struct resource *res;72int rc, i;7374pr_debug("PCI: Removing PHB %04x:%02x...\n",75pci_domain_nr(b), b->number);7677/* We cannot to remove a root bus that has children */78if (!(list_empty(&b->children) && list_empty(&b->devices)))79return -EBUSY;8081/* We -know- there aren't any child devices anymore at this stage82* and thus, we can safely unmap the IO space as it's not in use83*/84res = &phb->io_resource;85if (res->flags & IORESOURCE_IO) {86rc = pcibios_unmap_io_space(b);87if (rc) {88printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",89__func__, b->name);90return 1;91}92}9394ppc_iommu_unregister_device(phb);9596pseries_msi_free_domains(phb);9798/* Keep a reference so phb isn't freed yet */99get_device(&host_bridge->dev);100101/* Remove the PCI bus and unregister the bridge device from sysfs */102phb->bus = NULL;103pci_remove_bus(b);104host_bridge->bus = NULL;105device_unregister(&host_bridge->dev);106107/* Now release the IO resource */108if (res->flags & IORESOURCE_IO)109release_resource(res);110111/* Release memory resources */112for (i = 0; i < 3; ++i) {113res = &phb->mem_resources[i];114if (!(res->flags & IORESOURCE_MEM))115continue;116release_resource(res);117}118119/*120* The pci_controller data structure is freed by121* the pcibios_free_controller_deferred() callback;122* see pseries_root_bridge_prepare().123*/124put_device(&host_bridge->dev);125126return 0;127}128EXPORT_SYMBOL_GPL(remove_phb_dynamic);129130131