summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-09-07 13:24:16 -0500
committerBjorn Helgaas <bhelgaas@google.com>2017-09-07 13:24:16 -0500
commitd4fdf844c9c3debc080aea1be8b71d9d0aaa01dc (patch)
treeda9fa2b768f822194e33b49e1c913c0a6eec9368 /arch
parentcf5f9cc8e4e5e8e0ecc35f1c904d98f889be2c0f (diff)
parent606799cc5049ae4ccb51ba3242365ca2d411da13 (diff)
downloadlinux-d4fdf844c9c3debc080aea1be8b71d9d0aaa01dc.tar.bz2
Merge branch 'pci/irq-fixups' into next
* pci/irq-fixups: PCI: Inline and remove pcibios_update_irq() PCI: Remove unused pci_fixup_irqs() function sparc/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks unicore32/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks tile/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks MIPS: PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks m68k/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks sh/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks sh/PCI: Remove __init optimisations from IRQ mapping functions/data MIPS: PCI: Fix pcibios_scan_bus() NULL check code path
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/pci.c27
-rw-r--r--arch/alpha/kernel/sys_nautilus.c31
-rw-r--r--arch/m68k/coldfire/pci.c36
-rw-r--r--arch/mips/pci/pci-legacy.c30
-rw-r--r--arch/sh/drivers/pci/fixups-cayman.c2
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c2
-rw-r--r--arch/sh/drivers/pci/fixups-r7780rp.c2
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c6
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c4
-rw-r--r--arch/sh/drivers/pci/fixups-se7751.c2
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c2
-rw-r--r--arch/sh/drivers/pci/fixups-snapgear.c2
-rw-r--r--arch/sh/drivers/pci/fixups-titan.c4
-rw-r--r--arch/sh/drivers/pci/pci.c41
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c2
-rw-r--r--arch/sparc/kernel/leon_pci.c24
-rw-r--r--arch/tile/kernel/pci.c21
-rw-r--r--arch/tile/kernel/pci_gx.c21
-rw-r--r--arch/unicore32/kernel/pci.c35
19 files changed, 219 insertions, 75 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 5f387ee5b5c5..d558287c6133 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -312,8 +312,9 @@ common_init_pci(void)
{
struct pci_controller *hose;
struct list_head resources;
+ struct pci_host_bridge *bridge;
struct pci_bus *bus;
- int next_busno;
+ int ret, next_busno;
int need_domain_info = 0;
u32 pci_mem_end;
u32 sg_base;
@@ -336,11 +337,25 @@ common_init_pci(void)
pci_add_resource_offset(&resources, hose->mem_space,
hose->mem_space->start);
- bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
- hose, &resources);
- if (!bus)
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
continue;
- hose->bus = bus;
+
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = next_busno;
+ bridge->ops = alpha_mv.pci_ops;
+ bridge->swizzle_irq = alpha_mv.pci_swizzle;
+ bridge->map_irq = alpha_mv.pci_map_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ continue;
+ }
+
+ bus = hose->bus = bridge->bus;
hose->need_domain_info = need_domain_info;
next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose -
@@ -354,7 +369,6 @@ common_init_pci(void)
pcibios_claim_console_setup();
pci_assign_unassigned_resources();
- pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
for (hose = hose_head; hose; hose = hose->next) {
bus = hose->bus;
if (bus)
@@ -362,7 +376,6 @@ common_init_pci(void)
}
}
-
struct pci_controller * __init
alloc_pci_controller(void)
{
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index 2cfaa0e5c577..8ae04a121186 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -194,22 +194,46 @@ static struct resource irongate_mem = {
.name = "Irongate PCI MEM",
.flags = IORESOURCE_MEM,
};
+static struct resource busn_resource = {
+ .name = "PCI busn",
+ .start = 0,
+ .end = 255,
+ .flags = IORESOURCE_BUS,
+};
void __init
nautilus_init_pci(void)
{
struct pci_controller *hose = hose_head;
+ struct pci_host_bridge *bridge;
struct pci_bus *bus;
struct pci_dev *irongate;
unsigned long bus_align, bus_size, pci_mem;
unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+ int ret;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return;
+
+ pci_add_resource(&bridge->windows, &ioport_resource);
+ pci_add_resource(&bridge->windows, &iomem_resource);
+ pci_add_resource(&bridge->windows, &busn_resource);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = 0;
+ bridge->ops = alpha_mv.pci_ops;
+ bridge->swizzle_irq = alpha_mv.pci_swizzle;
+ bridge->map_irq = alpha_mv.pci_map_irq;
/* Scan our single hose. */
- bus = pci_scan_bus(0, alpha_mv.pci_ops, hose);
- if (!bus)
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
return;
+ }
- hose->bus = bus;
+ bus = hose->bus = bridge->bus;
pcibios_claim_one_bus(bus);
irongate = pci_get_bus_and_slot(0, 0);
@@ -254,7 +278,6 @@ nautilus_init_pci(void)
/* pci_common_swizzle() relies on bus->self being NULL
for the root bus, so just clear it. */
bus->self = NULL;
- pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
pci_bus_add_devices(bus);
}
diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c
index 6a640be48568..3097fa2ca746 100644
--- a/arch/m68k/coldfire/pci.c
+++ b/arch/m68k/coldfire/pci.c
@@ -243,6 +243,13 @@ static struct resource mcf_pci_io = {
.flags = IORESOURCE_IO,
};
+static struct resource busn_resource = {
+ .name = "PCI busn",
+ .start = 0,
+ .end = 255,
+ .flags = IORESOURCE_BUS,
+};
+
/*
* Interrupt mapping and setting.
*/
@@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
static int __init mcf_pci_init(void)
{
+ struct pci_host_bridge *bridge;
+ int ret;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return -ENOMEM;
+
pr_info("ColdFire: PCI bus initialization...\n");
/* Reset the external PCI bus */
@@ -312,14 +326,28 @@ static int __init mcf_pci_init(void)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(200));
- rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
- if (!rootbus)
- return -ENODEV;
+
+ pci_add_resource(&bridge->windows, &ioport_resource);
+ pci_add_resource(&bridge->windows, &iomem_resource);
+ pci_add_resource(&bridge->windows, &busn_resource);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = NULL;
+ bridge->busnr = 0;
+ bridge->ops = &mcf_pci_ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = mcf_pci_map_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ return ret;
+ }
+
+ rootbus = bridge->bus;
rootbus->resource[0] = &mcf_pci_io;
rootbus->resource[1] = &mcf_pci_mem;
- pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
pci_bus_size_bridges(rootbus);
pci_bus_assign_resources(rootbus);
pci_bus_add_devices(rootbus);
diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c
index 174575a9a112..fc7726088103 100644
--- a/arch/mips/pci/pci-legacy.c
+++ b/arch/mips/pci/pci-legacy.c
@@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose)
static int need_domain_info;
LIST_HEAD(resources);
struct pci_bus *bus;
+ struct pci_host_bridge *bridge;
+ int ret;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return;
if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY))
next_busno = (*hose->get_busno)();
@@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose)
pci_add_resource_offset(&resources,
hose->io_resource, hose->io_offset);
pci_add_resource(&resources, hose->busn_resource);
- bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
- &resources);
- hose->bus = bus;
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = next_busno;
+ bridge->ops = hose->pci_ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = pcibios_map_irq;
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ return;
+ }
+
+ hose->bus = bus = bridge->bus;
need_domain_info = need_domain_info || pci_domain_nr(bus);
set_pci_need_domain_info(hose, need_domain_info);
- if (!bus) {
- pci_free_resource_list(&resources);
- return;
- }
-
next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose -
reserve some space for bridges. */
@@ -224,8 +236,6 @@ static int __init pcibios_init(void)
list_for_each_entry(hose, &controllers, list)
pcibios_scanbus(hose);
- pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
-
pci_initialized = 1;
return 0;
diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c
index edc2fb7a5bb2..32467884d6f7 100644
--- a/arch/sh/drivers/pci/fixups-cayman.c
+++ b/arch/sh/drivers/pci/fixups-cayman.c
@@ -5,7 +5,7 @@
#include <cpu/irq.h>
#include "pci-sh5.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
int result = -1;
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 1d1c5a227e50..9d597f7ab8dd 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -76,7 +76,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
/*
* The interrupt routing semantics here are quite trivial.
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
index 57ed3f09d0c2..2c9b58f848dd 100644
--- a/arch/sh/drivers/pci/fixups-r7780rp.c
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -15,7 +15,7 @@
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return evt2irq(0xa20) + slot;
}
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index eaddb56c45c6..358ac104f08c 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -20,18 +20,18 @@
#define PCIMCR_MRSET_OFF 0xBFFFFFFF
#define PCIMCR_RFSH_OFF 0xFFFFFFFB
-static u8 rts7751r2d_irq_tab[] __initdata = {
+static u8 rts7751r2d_irq_tab[] = {
IRQ_PCI_INTA,
IRQ_PCI_INTB,
IRQ_PCI_INTC,
IRQ_PCI_INTD,
};
-static char lboxre2_irq_tab[] __initdata = {
+static char lboxre2_irq_tab[] = {
IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
if (mach_is_lboxre2())
return lboxre2_irq_tab[slot];
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
index c0a015ae6ecf..24e96dfbdb22 100644
--- a/arch/sh/drivers/pci/fixups-sdk7780.c
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -22,7 +22,7 @@
#define IRQ_INTD evt2irq(0xa80)
/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
-static char sdk7780_irq_tab[4][16] __initdata = {
+static char sdk7780_irq_tab[4][16] = {
/* INTA */
{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1 },
@@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = {
-1, -1, -1 },
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return sdk7780_irq_tab[pin-1][slot];
}
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c
index 84a88ca92008..1cb8d0ac4fdb 100644
--- a/arch/sh/drivers/pci/fixups-se7751.c
+++ b/arch/sh/drivers/pci/fixups-se7751.c
@@ -7,7 +7,7 @@
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
{
switch (slot) {
case 0: return evt2irq(0x3a0);
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
index 16207bef9f52..55ac1ba2c74f 100644
--- a/arch/sh/drivers/pci/fixups-sh03.c
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -4,7 +4,7 @@
#include <linux/pci.h>
#include <linux/sh_intc.h>
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c
index 6e33ba4cd076..a931e5928f58 100644
--- a/arch/sh/drivers/pci/fixups-snapgear.c
+++ b/arch/sh/drivers/pci/fixups-snapgear.c
@@ -19,7 +19,7 @@
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
int irq = -1;
diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c
index bd1addb1b8be..a9d563e479d5 100644
--- a/arch/sh/drivers/pci/fixups-titan.c
+++ b/arch/sh/drivers/pci/fixups-titan.c
@@ -19,7 +19,7 @@
#include <mach/titan.h>
#include "pci-sh4.h"
-static char titan_irq_tab[] __initdata = {
+static char titan_irq_tab[] = {
TITAN_IRQ_WAN,
TITAN_IRQ_LAN,
TITAN_IRQ_MPCIA,
@@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = {
TITAN_IRQ_USB,
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
int irq = titan_irq_tab[slot];
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index c99ee286b69f..357278c88e98 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose)
LIST_HEAD(resources);
struct resource *res;
resource_size_t offset;
- int i;
- struct pci_bus *bus;
+ int i, ret;
+ struct pci_host_bridge *bridge;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return;
for (i = 0; i < hose->nr_resources; i++) {
res = hose->resources + i;
@@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose)
pci_add_resource_offset(&resources, res, offset);
}
- bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
- &resources);
- hose->bus = bus;
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = next_busno;
+ bridge->ops = hose->pci_ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = pcibios_map_platform_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ return;
+ }
+
+ hose->bus = bridge->bus;
need_domain_info = need_domain_info || hose->index;
hose->need_domain_info = need_domain_info;
- if (!bus) {
- pci_free_resource_list(&resources);
- return;
- }
-
- next_busno = bus->busn_res.end + 1;
+ next_busno = hose->bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose -
reserve some space for bridges. */
if (next_busno > 224) {
@@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose)
need_domain_info = 1;
}
- pci_bus_size_bridges(bus);
- pci_bus_assign_resources(bus);
- pci_bus_add_devices(bus);
+ pci_bus_size_bridges(hose->bus);
+ pci_bus_assign_resources(hose->bus);
+ pci_bus_add_devices(hose->bus);
}
/*
@@ -144,8 +155,6 @@ static int __init pcibios_init(void)
for (hose = hose_head; hose; hose = hose->next)
pcibios_scanbus(hose);
- pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
-
dma_debug_add_bus(&pci_bus_type);
pci_initialized = 1;
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index a162a7f86b2e..0167a7352719 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
return 0;
}
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return evt2irq(0xae0);
}
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index 4371f72ff025..7b5c7072b006 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
{
LIST_HEAD(resources);
struct pci_bus *root_bus;
+ struct pci_host_bridge *bridge;
+ int ret;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return;
pci_add_resource_offset(&resources, &info->io_space,
info->io_space.start - 0x1000);
@@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
info->busn.flags = IORESOURCE_BUS;
pci_add_resource(&resources, &info->busn);
- root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
- &resources);
- if (!root_bus) {
- pci_free_resource_list(&resources);
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = &ofdev->dev;
+ bridge->sysdata = info;
+ bridge->busnr = 0;
+ bridge->ops = info->ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = info->map_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
return;
}
- /* Setup IRQs of all devices using custom routines */
- pci_fixup_irqs(pci_common_swizzle, info->map_irq);
+ root_bus = bridge->bus;
/* Assign devices with resources */
pci_assign_unassigned_resources();
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index bc6656b5708b..884826157765 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -274,6 +274,7 @@ static void fixup_read_and_payload_sizes(void)
*/
int __init pcibios_init(void)
{
+ struct pci_host_bridge *bridge;
int i;
pr_info("PCI: Probing PCI hardware\n");
@@ -306,16 +307,26 @@ int __init pcibios_init(void)
pci_add_resource(&resources, &ioport_resource);
pci_add_resource(&resources, &iomem_resource);
- bus = pci_scan_root_bus(NULL, 0, controller->ops,
- controller, &resources);
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ break;
+
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = controller;
+ bridge->busnr = 0;
+ bridge->ops = controller->ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = tile_map_irq;
+
+ pci_scan_root_bus_bridge(bridge);
+ bus = bridge->bus;
controller->root_bus = bus;
controller->last_busno = bus->busn_res.end;
}
}
- /* Do machine dependent PCI interrupt routing */
- pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
-
/*
* This comes from the generic Linux PCI driver.
*
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index b554a68eea1b..e68317083ac7 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -669,6 +669,7 @@ int __init pcibios_init(void)
resource_size_t offset;
LIST_HEAD(resources);
int next_busno;
+ struct pci_host_bridge *bridge;
int i;
tile_pci_init();
@@ -881,15 +882,25 @@ int __init pcibios_init(void)
controller->mem_offset);
pci_add_resource(&resources, &controller->io_space);
controller->first_busno = next_busno;
- bus = pci_scan_root_bus(NULL, next_busno, controller->ops,
- controller, &resources);
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ break;
+
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = controller;
+ bridge->busnr = next_busno;
+ bridge->ops = controller->ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = tile_map_irq;
+
+ pci_scan_root_bus_bridge(bridge);
+ bus = bridge->bus;
controller->root_bus = bus;
next_busno = bus->busn_res.end + 1;
}
- /* Do machine dependent PCI interrupt routing */
- pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
-
/*
* This comes from the generic Linux PCI driver.
*
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index 1053bca1f8aa..9f26840e41b1 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -101,7 +101,7 @@ void pci_puv3_preinit(void)
writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD);
}
-static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
if (dev->bus->number == 0) {
#ifdef CONFIG_ARCH_FPGA /* 4 pci slots */
@@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibios_fixup_bus);
+static struct resource busn_resource = {
+ .name = "PCI busn",
+ .start = 0,
+ .end = 255,
+ .flags = IORESOURCE_BUS,
+};
+
static int __init pci_common_init(void)
{
struct pci_bus *puv3_bus;
+ struct pci_host_bridge *bridge;
+ int ret;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return -ENOMEM;
pci_puv3_preinit();
- puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL);
+ pci_add_resource(&bridge->windows, &ioport_resource);
+ pci_add_resource(&bridge->windows, &iomem_resource);
+ pci_add_resource(&bridge->windows, &busn_resource);
+ bridge->sysdata = NULL;
+ bridge->busnr = 0;
+ bridge->ops = &pci_puv3_ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = pci_puv3_map_irq;
+
+ /* Scan our single hose. */
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ return;
+ }
+
+ puv3_bus = bridge->bus;
if (!puv3_bus)
panic("PCI: unable to scan bus!");
- pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq);
-
pci_bus_size_bridges(puv3_bus);
pci_bus_assign_resources(puv3_bus);
pci_bus_add_devices(puv3_bus);