Linux Audio

Check our new training course

Loading...
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);
v4.10.11
 
  1/*
  2 * Derived from "arch/powerpc/platforms/pseries/pci_dlpar.c"
  3 *
  4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
  5 * Copyright (C) 2005 International Business Machines
  6 *
  7 * Updates, 2005, John Rose <johnrose@austin.ibm.com>
  8 * Updates, 2005, Linas Vepstas <linas@austin.ibm.com>
  9 * Updates, 2013, Gavin Shan <shangw@linux.vnet.ibm.com>
 10 *
 11 * This program is free software; you can redistribute it and/or modify
 12 * it under the terms of the GNU General Public License as published by
 13 * the Free Software Foundation; either version 2 of the License, or
 14 * (at your option) any later version.
 15 */
 16
 17#include <linux/pci.h>
 18#include <linux/export.h>
 
 19#include <asm/pci-bridge.h>
 20#include <asm/ppc-pci.h>
 21#include <asm/firmware.h>
 22#include <asm/eeh.h>
 23
 24static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
 25					       struct device_node *dn)
 26{
 27	struct pci_bus *child = NULL;
 28	struct pci_bus *tmp;
 29
 30	if (pci_bus_to_OF_node(bus) == dn)
 31		return bus;
 32
 33	list_for_each_entry(tmp, &bus->children, node) {
 34		child = find_bus_among_children(tmp, dn);
 35		if (child)
 36			break;
 37	}
 38
 39	return child;
 40}
 41
 42struct pci_bus *pci_find_bus_by_node(struct device_node *dn)
 43{
 44	struct pci_dn *pdn = PCI_DN(dn);
 45
 46	if (!pdn  || !pdn->phb || !pdn->phb->bus)
 47		return NULL;
 48
 49	return find_bus_among_children(pdn->phb->bus, dn);
 50}
 51EXPORT_SYMBOL_GPL(pci_find_bus_by_node);
 52
 53/**
 54 * pcibios_release_device - release PCI device
 55 * @dev: PCI device
 56 *
 57 * The function is called before releasing the indicated PCI device.
 58 */
 59void pcibios_release_device(struct pci_dev *dev)
 60{
 61	struct pci_controller *phb = pci_bus_to_host(dev->bus);
 62
 63	eeh_remove_device(dev);
 64
 65	if (phb->controller_ops.release_device)
 66		phb->controller_ops.release_device(dev);
 
 
 
 
 
 
 67}
 68
 69/**
 70 * pci_hp_remove_devices - remove all devices under this bus
 71 * @bus: the indicated PCI bus
 72 *
 73 * Remove all of the PCI devices under this bus both from the
 74 * linux pci device tree, and from the powerpc EEH address cache.
 75 */
 76void pci_hp_remove_devices(struct pci_bus *bus)
 77{
 78	struct pci_dev *dev, *tmp;
 79	struct pci_bus *child_bus;
 80
 81	/* First go down child busses */
 82	list_for_each_entry(child_bus, &bus->children, node)
 83		pci_hp_remove_devices(child_bus);
 84
 85	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
 86		 pci_domain_nr(bus),  bus->number);
 87	list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
 88		pr_debug("   Removing %s...\n", pci_name(dev));
 89		pci_stop_and_remove_bus_device(dev);
 90	}
 91}
 92EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
 93
 94/**
 95 * pci_hp_add_devices - adds new pci devices to bus
 96 * @bus: the indicated PCI bus
 97 *
 98 * This routine will find and fixup new pci devices under
 99 * the indicated bus. This routine presumes that there
100 * might already be some devices under this bridge, so
101 * it carefully tries to add only new devices.  (And that
102 * is how this routine differs from other, similar pcibios
103 * routines.)
104 */
105void pci_hp_add_devices(struct pci_bus *bus)
106{
107	int slotno, mode, pass, max;
108	struct pci_dev *dev;
109	struct pci_controller *phb;
110	struct device_node *dn = pci_bus_to_OF_node(bus);
111
112	eeh_add_device_tree_early(PCI_DN(dn));
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		pcibios_setup_bus_devices(bus);
135		max = bus->busn_res.start;
136		for (pass = 0; pass < 2; pass++) {
137			list_for_each_entry(dev, &bus->devices, bus_list) {
138				if (pci_is_bridge(dev))
139					max = pci_scan_bridge(bus, dev,
140							      max, pass);
141			}
142		}
 
 
 
 
143	}
144	pcibios_finish_adding_to_bus(bus);
145}
146EXPORT_SYMBOL_GPL(pci_hp_add_devices);