/*
 * Derived from "arch/powerpc/platforms/pseries/pci_dlpar.c"
 *
 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
 * Copyright (C) 2005 International Business Machines
 *
 * Updates, 2005, John Rose <johnrose@austin.ibm.com>
 * Updates, 2005, Linas Vepstas <linas@austin.ibm.com>
 * Updates, 2013, Gavin Shan <shangw@linux.vnet.ibm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/pci.h>
#include <linux/export.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
#include <asm/eeh.h>

/**
 * pcibios_release_device - release PCI device
 * @dev: PCI device
 *
 * The function is called before releasing the indicated PCI device.
 */
void pcibios_release_device(struct pci_dev *dev)
{
	struct pci_controller *phb = pci_bus_to_host(dev->bus);

	eeh_remove_device(dev);

	if (phb->controller_ops.release_device)
		phb->controller_ops.release_device(dev);
}

/**
 * pcibios_remove_pci_devices - remove all devices under this bus
 * @bus: the indicated PCI bus
 *
 * Remove all of the PCI devices under this bus both from the
 * linux pci device tree, and from the powerpc EEH address cache.
 */
void pcibios_remove_pci_devices(struct pci_bus *bus)
{
	struct pci_dev *dev, *tmp;
	struct pci_bus *child_bus;

	/* First go down child busses */
	list_for_each_entry(child_bus, &bus->children, node)
		pcibios_remove_pci_devices(child_bus);

	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
		 pci_domain_nr(bus),  bus->number);
	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
		pr_debug("   Removing %s...\n", pci_name(dev));
		pci_stop_and_remove_bus_device(dev);
	}
}

EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);

/**
 * pcibios_add_pci_devices - adds new pci devices to bus
 * @bus: the indicated PCI bus
 *
 * This routine will find and fixup new pci devices under
 * the indicated bus. This routine presumes that there
 * might already be some devices under this bridge, so
 * it carefully tries to add only new devices.  (And that
 * is how this routine differs from other, similar pcibios
 * routines.)
 */
void pcibios_add_pci_devices(struct pci_bus * bus)
{
	int slotno, mode, pass, max;
	struct pci_dev *dev;
	struct pci_controller *phb;
	struct device_node *dn = pci_bus_to_OF_node(bus);

	eeh_add_device_tree_early(PCI_DN(dn));

	phb = pci_bus_to_host(bus);

	mode = PCI_PROBE_NORMAL;
	if (phb->controller_ops.probe_mode)
		mode = phb->controller_ops.probe_mode(bus);

	if (mode == PCI_PROBE_DEVTREE) {
		/* use ofdt-based probe */
		of_rescan_bus(dn, bus);
	} else if (mode == PCI_PROBE_NORMAL) {
		/*
		 * Use legacy probe. In the partial hotplug case, we
		 * probably have grandchildren devices unplugged. So
		 * we don't check the return value from pci_scan_slot() in
		 * order for fully rescan all the way down to pick them up.
		 * They can have been removed during partial hotplug.
		 */
		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
		pcibios_setup_bus_devices(bus);
		max = bus->busn_res.start;
		for (pass = 0; pass < 2; pass++) {
			list_for_each_entry(dev, &bus->devices, bus_list) {
				if (pci_is_bridge(dev))
					max = pci_scan_bridge(bus, dev,
							      max, pass);
			}
		}
	}
	pcibios_finish_adding_to_bus(bus);
}
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
