Linux Audio

Check our new training course

Loading...
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Derived from "arch/powerpc/platforms/pseries/pci_dlpar.c"
  4 *
  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 * Updates, 2013, Gavin Shan <shangw@linux.vnet.ibm.com>
 11 */
 12
 13#include <linux/pci.h>
 14#include <linux/export.h>
 
 15#include <asm/pci-bridge.h>
 16#include <asm/ppc-pci.h>
 17#include <asm/firmware.h>
 18#include <asm/eeh.h>
 19
 20static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
 21					       struct device_node *dn)
 22{
 23	struct pci_bus *child = NULL;
 24	struct pci_bus *tmp;
 25
 26	if (pci_bus_to_OF_node(bus) == dn)
 27		return bus;
 28
 29	list_for_each_entry(tmp, &bus->children, node) {
 30		child = find_bus_among_children(tmp, dn);
 31		if (child)
 32			break;
 33	}
 34
 35	return child;
 36}
 37
 38struct pci_bus *pci_find_bus_by_node(struct device_node *dn)
 39{
 40	struct pci_dn *pdn = PCI_DN(dn);
 41
 42	if (!pdn  || !pdn->phb || !pdn->phb->bus)
 43		return NULL;
 44
 45	return find_bus_among_children(pdn->phb->bus, dn);
 46}
 47EXPORT_SYMBOL_GPL(pci_find_bus_by_node);
 48
 49/**
 50 * pcibios_release_device - release PCI device
 51 * @dev: PCI device
 52 *
 53 * The function is called before releasing the indicated PCI device.
 54 */
 55void pcibios_release_device(struct pci_dev *dev)
 56{
 57	struct pci_controller *phb = pci_bus_to_host(dev->bus);
 58	struct pci_dn *pdn = pci_get_pdn(dev);
 59
 60	if (phb->controller_ops.release_device)
 61		phb->controller_ops.release_device(dev);
 62
 63	/* free()ing the pci_dn has been deferred to us, do it now */
 64	if (pdn && (pdn->flags & PCI_DN_FLAG_DEAD)) {
 65		pci_dbg(dev, "freeing dead pdn\n");
 66		kfree(pdn);
 67	}
 68}
 69
 70/**
 71 * pci_hp_remove_devices - remove all devices under this bus
 72 * @bus: the indicated PCI bus
 73 *
 74 * Remove all of the PCI devices under this bus both from the
 75 * linux pci device tree, and from the powerpc EEH address cache.
 76 */
 77void pci_hp_remove_devices(struct pci_bus *bus)
 78{
 79	struct pci_dev *dev, *tmp;
 80	struct pci_bus *child_bus;
 81
 82	/* First go down child busses */
 83	list_for_each_entry(child_bus, &bus->children, node)
 84		pci_hp_remove_devices(child_bus);
 85
 86	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
 87		 pci_domain_nr(bus),  bus->number);
 88	list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
 89		pr_debug("   Removing %s...\n", pci_name(dev));
 90		pci_stop_and_remove_bus_device(dev);
 91	}
 92}
 93EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
 94
 95/**
 96 * pci_hp_add_devices - adds new pci devices to bus
 97 * @bus: the indicated PCI bus
 98 *
 99 * This routine will find and fixup new pci devices under
100 * the indicated bus. This routine presumes that there
101 * might already be some devices under this bridge, so
102 * it carefully tries to add only new devices.  (And that
103 * is how this routine differs from other, similar pcibios
104 * routines.)
105 */
106void pci_hp_add_devices(struct pci_bus *bus)
107{
108	int slotno, mode, max;
109	struct pci_dev *dev;
110	struct pci_controller *phb;
111	struct device_node *dn = pci_bus_to_OF_node(bus);
112
113	phb = pci_bus_to_host(bus);
114
115	mode = PCI_PROBE_NORMAL;
116	if (phb->controller_ops.probe_mode)
117		mode = phb->controller_ops.probe_mode(bus);
118
119	if (mode == PCI_PROBE_DEVTREE) {
120		/* use ofdt-based probe */
121		of_rescan_bus(dn, bus);
122	} else if (mode == PCI_PROBE_NORMAL &&
123		   dn->child && PCI_DN(dn->child)) {
124		/*
125		 * Use legacy probe. In the partial hotplug case, we
126		 * probably have grandchildren devices unplugged. So
127		 * we don't check the return value from pci_scan_slot() in
128		 * order for fully rescan all the way down to pick them up.
129		 * They can have been removed during partial hotplug.
130		 */
131		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
132		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
133		max = bus->busn_res.start;
134		/*
135		 * Scan bridges that are already configured. We don't touch
136		 * them unless they are misconfigured (which will be done in
137		 * the second scan below).
138		 */
139		for_each_pci_bridge(dev, bus)
140			max = pci_scan_bridge(bus, dev, max, 0);
141
142		/* Scan bridges that need to be reconfigured */
143		for_each_pci_bridge(dev, bus)
144			max = pci_scan_bridge(bus, dev, max, 1);
145	}
146	pcibios_finish_adding_to_bus(bus);
147}
148EXPORT_SYMBOL_GPL(pci_hp_add_devices);
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Derived from "arch/powerpc/platforms/pseries/pci_dlpar.c"
  4 *
  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 * Updates, 2013, Gavin Shan <shangw@linux.vnet.ibm.com>
 11 */
 12
 13#include <linux/pci.h>
 14#include <linux/export.h>
 15#include <linux/of.h>
 16#include <asm/pci-bridge.h>
 17#include <asm/ppc-pci.h>
 18#include <asm/firmware.h>
 19#include <asm/eeh.h>
 20
 21static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
 22					       struct device_node *dn)
 23{
 24	struct pci_bus *child = NULL;
 25	struct pci_bus *tmp;
 26
 27	if (pci_bus_to_OF_node(bus) == dn)
 28		return bus;
 29
 30	list_for_each_entry(tmp, &bus->children, node) {
 31		child = find_bus_among_children(tmp, dn);
 32		if (child)
 33			break;
 34	}
 35
 36	return child;
 37}
 38
 39struct pci_bus *pci_find_bus_by_node(struct device_node *dn)
 40{
 41	struct pci_dn *pdn = PCI_DN(dn);
 42
 43	if (!pdn  || !pdn->phb || !pdn->phb->bus)
 44		return NULL;
 45
 46	return find_bus_among_children(pdn->phb->bus, dn);
 47}
 48EXPORT_SYMBOL_GPL(pci_find_bus_by_node);
 49
 50/**
 51 * pcibios_release_device - release PCI device
 52 * @dev: PCI device
 53 *
 54 * The function is called before releasing the indicated PCI device.
 55 */
 56void pcibios_release_device(struct pci_dev *dev)
 57{
 58	struct pci_controller *phb = pci_bus_to_host(dev->bus);
 59	struct pci_dn *pdn = pci_get_pdn(dev);
 60
 61	if (phb->controller_ops.release_device)
 62		phb->controller_ops.release_device(dev);
 63
 64	/* free()ing the pci_dn has been deferred to us, do it now */
 65	if (pdn && (pdn->flags & PCI_DN_FLAG_DEAD)) {
 66		pci_dbg(dev, "freeing dead pdn\n");
 67		kfree(pdn);
 68	}
 69}
 70
 71/**
 72 * pci_hp_remove_devices - remove all devices under this bus
 73 * @bus: the indicated PCI bus
 74 *
 75 * Remove all of the PCI devices under this bus both from the
 76 * linux pci device tree, and from the powerpc EEH address cache.
 77 */
 78void pci_hp_remove_devices(struct pci_bus *bus)
 79{
 80	struct pci_dev *dev, *tmp;
 81	struct pci_bus *child_bus;
 82
 83	/* First go down child busses */
 84	list_for_each_entry(child_bus, &bus->children, node)
 85		pci_hp_remove_devices(child_bus);
 86
 87	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
 88		 pci_domain_nr(bus),  bus->number);
 89	list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
 90		pr_debug("   Removing %s...\n", pci_name(dev));
 91		pci_stop_and_remove_bus_device(dev);
 92	}
 93}
 94EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
 95
 96/**
 97 * pci_hp_add_devices - adds new pci devices to bus
 98 * @bus: the indicated PCI bus
 99 *
100 * This routine will find and fixup new pci devices under
101 * the indicated bus. This routine presumes that there
102 * might already be some devices under this bridge, so
103 * it carefully tries to add only new devices.  (And that
104 * is how this routine differs from other, similar pcibios
105 * routines.)
106 */
107void pci_hp_add_devices(struct pci_bus *bus)
108{
109	int slotno, mode, max;
110	struct pci_dev *dev;
111	struct pci_controller *phb;
112	struct device_node *dn = pci_bus_to_OF_node(bus);
113
114	phb = pci_bus_to_host(bus);
115
116	mode = PCI_PROBE_NORMAL;
117	if (phb->controller_ops.probe_mode)
118		mode = phb->controller_ops.probe_mode(bus);
119
120	if (mode == PCI_PROBE_DEVTREE) {
121		/* use ofdt-based probe */
122		of_rescan_bus(dn, bus);
123	} else if (mode == PCI_PROBE_NORMAL &&
124		   dn->child && PCI_DN(dn->child)) {
125		/*
126		 * Use legacy probe. In the partial hotplug case, we
127		 * probably have grandchildren devices unplugged. So
128		 * we don't check the return value from pci_scan_slot() in
129		 * order for fully rescan all the way down to pick them up.
130		 * They can have been removed during partial hotplug.
131		 */
132		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
133		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
134		max = bus->busn_res.start;
135		/*
136		 * Scan bridges that are already configured. We don't touch
137		 * them unless they are misconfigured (which will be done in
138		 * the second scan below).
139		 */
140		for_each_pci_bridge(dev, bus)
141			max = pci_scan_bridge(bus, dev, max, 0);
142
143		/* Scan bridges that need to be reconfigured */
144		for_each_pci_bridge(dev, bus)
145			max = pci_scan_bridge(bus, dev, max, 1);
146	}
147	pcibios_finish_adding_to_bus(bus);
148}
149EXPORT_SYMBOL_GPL(pci_hp_add_devices);