mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.4 KiB
104 lines
2.4 KiB
// SPDX-License-Identifier: GPL-2.0-or-later |
|
/* |
|
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. |
|
* <[email protected]> |
|
* and Arnd Bergmann, IBM Corp. |
|
*/ |
|
|
|
#undef DEBUG |
|
|
|
#include <linux/string.h> |
|
#include <linux/kernel.h> |
|
#include <linux/init.h> |
|
#include <linux/export.h> |
|
#include <linux/mod_devicetable.h> |
|
#include <linux/pci.h> |
|
#include <linux/of.h> |
|
#include <linux/of_device.h> |
|
#include <linux/of_platform.h> |
|
#include <linux/atomic.h> |
|
|
|
#include <asm/errno.h> |
|
#include <asm/topology.h> |
|
#include <asm/pci-bridge.h> |
|
#include <asm/ppc-pci.h> |
|
#include <asm/eeh.h> |
|
|
|
#ifdef CONFIG_PPC_OF_PLATFORM_PCI |
|
|
|
/* The probing of PCI controllers from of_platform is currently |
|
* 64 bits only, mostly due to gratuitous differences between |
|
* the 32 and 64 bits PCI code on PowerPC and the 32 bits one |
|
* lacking some bits needed here. |
|
*/ |
|
|
|
static int of_pci_phb_probe(struct platform_device *dev) |
|
{ |
|
struct pci_controller *phb; |
|
|
|
/* Check if we can do that ... */ |
|
if (ppc_md.pci_setup_phb == NULL) |
|
return -ENODEV; |
|
|
|
pr_info("Setting up PCI bus %pOF\n", dev->dev.of_node); |
|
|
|
/* Alloc and setup PHB data structure */ |
|
phb = pcibios_alloc_controller(dev->dev.of_node); |
|
if (!phb) |
|
return -ENODEV; |
|
|
|
/* Setup parent in sysfs */ |
|
phb->parent = &dev->dev; |
|
|
|
/* Setup the PHB using arch provided callback */ |
|
if (ppc_md.pci_setup_phb(phb)) { |
|
pcibios_free_controller(phb); |
|
return -ENODEV; |
|
} |
|
|
|
/* Process "ranges" property */ |
|
pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); |
|
|
|
/* Init pci_dn data structures */ |
|
pci_devs_phb_init_dynamic(phb); |
|
|
|
/* Create EEH PE for the PHB */ |
|
eeh_phb_pe_create(phb); |
|
|
|
/* Scan the bus */ |
|
pcibios_scan_phb(phb); |
|
if (phb->bus == NULL) |
|
return -ENXIO; |
|
|
|
/* Claim resources. This might need some rework as well depending |
|
* whether we are doing probe-only or not, like assigning unassigned |
|
* resources etc... |
|
*/ |
|
pcibios_claim_one_bus(phb->bus); |
|
|
|
/* Add probed PCI devices to the device model */ |
|
pci_bus_add_devices(phb->bus); |
|
|
|
return 0; |
|
} |
|
|
|
static const struct of_device_id of_pci_phb_ids[] = { |
|
{ .type = "pci", }, |
|
{ .type = "pcix", }, |
|
{ .type = "pcie", }, |
|
{ .type = "pciex", }, |
|
{ .type = "ht", }, |
|
{} |
|
}; |
|
|
|
static struct platform_driver of_pci_phb_driver = { |
|
.probe = of_pci_phb_probe, |
|
.driver = { |
|
.name = "of-pci", |
|
.of_match_table = of_pci_phb_ids, |
|
}, |
|
}; |
|
|
|
builtin_platform_driver(of_pci_phb_driver); |
|
|
|
#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
|
|
|