Commit d4fdf844 authored by Bjorn Helgaas's avatar Bjorn Helgaas

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
parents cf5f9cc8 606799cc
...@@ -312,8 +312,9 @@ common_init_pci(void) ...@@ -312,8 +312,9 @@ common_init_pci(void)
{ {
struct pci_controller *hose; struct pci_controller *hose;
struct list_head resources; struct list_head resources;
struct pci_host_bridge *bridge;
struct pci_bus *bus; struct pci_bus *bus;
int next_busno; int ret, next_busno;
int need_domain_info = 0; int need_domain_info = 0;
u32 pci_mem_end; u32 pci_mem_end;
u32 sg_base; u32 sg_base;
...@@ -336,11 +337,25 @@ common_init_pci(void) ...@@ -336,11 +337,25 @@ common_init_pci(void)
pci_add_resource_offset(&resources, hose->mem_space, pci_add_resource_offset(&resources, hose->mem_space,
hose->mem_space->start); hose->mem_space->start);
bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, bridge = pci_alloc_host_bridge(0);
hose, &resources); if (!bridge)
if (!bus)
continue; 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; hose->need_domain_info = need_domain_info;
next_busno = bus->busn_res.end + 1; next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose - /* Don't allow 8-bit bus number overflow inside the hose -
...@@ -354,7 +369,6 @@ common_init_pci(void) ...@@ -354,7 +369,6 @@ common_init_pci(void)
pcibios_claim_console_setup(); pcibios_claim_console_setup();
pci_assign_unassigned_resources(); pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
for (hose = hose_head; hose; hose = hose->next) { for (hose = hose_head; hose; hose = hose->next) {
bus = hose->bus; bus = hose->bus;
if (bus) if (bus)
...@@ -362,7 +376,6 @@ common_init_pci(void) ...@@ -362,7 +376,6 @@ common_init_pci(void)
} }
} }
struct pci_controller * __init struct pci_controller * __init
alloc_pci_controller(void) alloc_pci_controller(void)
{ {
......
...@@ -194,22 +194,46 @@ static struct resource irongate_mem = { ...@@ -194,22 +194,46 @@ static struct resource irongate_mem = {
.name = "Irongate PCI MEM", .name = "Irongate PCI MEM",
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
static struct resource busn_resource = {
.name = "PCI busn",
.start = 0,
.end = 255,
.flags = IORESOURCE_BUS,
};
void __init void __init
nautilus_init_pci(void) nautilus_init_pci(void)
{ {
struct pci_controller *hose = hose_head; struct pci_controller *hose = hose_head;
struct pci_host_bridge *bridge;
struct pci_bus *bus; struct pci_bus *bus;
struct pci_dev *irongate; struct pci_dev *irongate;
unsigned long bus_align, bus_size, pci_mem; unsigned long bus_align, bus_size, pci_mem;
unsigned long memtop = max_low_pfn << PAGE_SHIFT; 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. */ /* Scan our single hose. */
bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); ret = pci_scan_root_bus_bridge(bridge);
if (!bus) if (ret) {
pci_free_host_bridge(bridge);
return; return;
}
hose->bus = bus; bus = hose->bus = bridge->bus;
pcibios_claim_one_bus(bus); pcibios_claim_one_bus(bus);
irongate = pci_get_bus_and_slot(0, 0); irongate = pci_get_bus_and_slot(0, 0);
...@@ -254,7 +278,6 @@ nautilus_init_pci(void) ...@@ -254,7 +278,6 @@ nautilus_init_pci(void)
/* pci_common_swizzle() relies on bus->self being NULL /* pci_common_swizzle() relies on bus->self being NULL
for the root bus, so just clear it. */ for the root bus, so just clear it. */
bus->self = NULL; bus->self = NULL;
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
pci_bus_add_devices(bus); pci_bus_add_devices(bus);
} }
......
...@@ -243,6 +243,13 @@ static struct resource mcf_pci_io = { ...@@ -243,6 +243,13 @@ static struct resource mcf_pci_io = {
.flags = IORESOURCE_IO, .flags = IORESOURCE_IO,
}; };
static struct resource busn_resource = {
.name = "PCI busn",
.start = 0,
.end = 255,
.flags = IORESOURCE_BUS,
};
/* /*
* Interrupt mapping and setting. * Interrupt mapping and setting.
*/ */
...@@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ...@@ -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) 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"); pr_info("ColdFire: PCI bus initialization...\n");
/* Reset the external PCI bus */ /* Reset the external PCI bus */
...@@ -312,14 +326,28 @@ static int __init mcf_pci_init(void) ...@@ -312,14 +326,28 @@ static int __init mcf_pci_init(void)
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(200)); schedule_timeout(msecs_to_jiffies(200));
rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
if (!rootbus) pci_add_resource(&bridge->windows, &ioport_resource);
return -ENODEV; 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[0] = &mcf_pci_io;
rootbus->resource[1] = &mcf_pci_mem; rootbus->resource[1] = &mcf_pci_mem;
pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
pci_bus_size_bridges(rootbus); pci_bus_size_bridges(rootbus);
pci_bus_assign_resources(rootbus); pci_bus_assign_resources(rootbus);
pci_bus_add_devices(rootbus); pci_bus_add_devices(rootbus);
......
...@@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) ...@@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose)
static int need_domain_info; static int need_domain_info;
LIST_HEAD(resources); LIST_HEAD(resources);
struct pci_bus *bus; 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)) if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY))
next_busno = (*hose->get_busno)(); next_busno = (*hose->get_busno)();
...@@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose) ...@@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose)
pci_add_resource_offset(&resources, pci_add_resource_offset(&resources,
hose->io_resource, hose->io_offset); hose->io_resource, hose->io_offset);
pci_add_resource(&resources, hose->busn_resource); pci_add_resource(&resources, hose->busn_resource);
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, list_splice_init(&resources, &bridge->windows);
&resources); bridge->dev.parent = NULL;
hose->bus = bus; 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); need_domain_info = need_domain_info || pci_domain_nr(bus);
set_pci_need_domain_info(hose, need_domain_info); set_pci_need_domain_info(hose, need_domain_info);
if (!bus) {
pci_free_resource_list(&resources);
return;
}
next_busno = bus->busn_res.end + 1; next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose - /* Don't allow 8-bit bus number overflow inside the hose -
reserve some space for bridges. */ reserve some space for bridges. */
...@@ -224,8 +236,6 @@ static int __init pcibios_init(void) ...@@ -224,8 +236,6 @@ static int __init pcibios_init(void)
list_for_each_entry(hose, &controllers, list) list_for_each_entry(hose, &controllers, list)
pcibios_scanbus(hose); pcibios_scanbus(hose);
pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
pci_initialized = 1; pci_initialized = 1;
return 0; return 0;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <cpu/irq.h> #include <cpu/irq.h>
#include "pci-sh5.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; int result = -1;
......
...@@ -76,7 +76,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev) ...@@ -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); 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. * The interrupt routing semantics here are quite trivial.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/sh_intc.h> #include <linux/sh_intc.h>
#include "pci-sh4.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; return evt2irq(0xa20) + slot;
} }
...@@ -20,18 +20,18 @@ ...@@ -20,18 +20,18 @@
#define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_MRSET_OFF 0xBFFFFFFF
#define PCIMCR_RFSH_OFF 0xFFFFFFFB #define PCIMCR_RFSH_OFF 0xFFFFFFFB
static u8 rts7751r2d_irq_tab[] __initdata = { static u8 rts7751r2d_irq_tab[] = {
IRQ_PCI_INTA, IRQ_PCI_INTA,
IRQ_PCI_INTB, IRQ_PCI_INTB,
IRQ_PCI_INTC, IRQ_PCI_INTC,
IRQ_PCI_INTD, IRQ_PCI_INTD,
}; };
static char lboxre2_irq_tab[] __initdata = { static char lboxre2_irq_tab[] = {
IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, 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()) if (mach_is_lboxre2())
return lboxre2_irq_tab[slot]; return lboxre2_irq_tab[slot];
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define IRQ_INTD evt2irq(0xa80) #define IRQ_INTD evt2irq(0xa80)
/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ /* 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 */ /* INTA */
{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1 }, -1, -1, -1, -1, -1, -1 },
...@@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { ...@@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = {
-1, -1, -1 }, -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]; return sdk7780_irq_tab[pin-1][slot];
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/sh_intc.h> #include <linux/sh_intc.h>
#include "pci-sh4.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) { switch (slot) {
case 0: return evt2irq(0x3a0); case 0: return evt2irq(0x3a0);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/sh_intc.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; int irq;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/sh_intc.h> #include <linux/sh_intc.h>
#include "pci-sh4.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; int irq = -1;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <mach/titan.h> #include <mach/titan.h>
#include "pci-sh4.h" #include "pci-sh4.h"
static char titan_irq_tab[] __initdata = { static char titan_irq_tab[] = {
TITAN_IRQ_WAN, TITAN_IRQ_WAN,
TITAN_IRQ_LAN, TITAN_IRQ_LAN,
TITAN_IRQ_MPCIA, TITAN_IRQ_MPCIA,
...@@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { ...@@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = {
TITAN_IRQ_USB, 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]; int irq = titan_irq_tab[slot];
......
...@@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose) ...@@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose)
LIST_HEAD(resources); LIST_HEAD(resources);
struct resource *res; struct resource *res;
resource_size_t offset; resource_size_t offset;
int i; int i, ret;
struct pci_bus *bus; struct pci_host_bridge *bridge;
bridge = pci_alloc_host_bridge(0);
if (!bridge)
return;
for (i = 0; i < hose->nr_resources; i++) { for (i = 0; i < hose->nr_resources; i++) {
res = hose->resources + i; res = hose->resources + i;
...@@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose) ...@@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose)
pci_add_resource_offset(&resources, res, offset); pci_add_resource_offset(&resources, res, offset);
} }
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, list_splice_init(&resources, &bridge->windows);
&resources); bridge->dev.parent = NULL;
hose->bus = bus; 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; need_domain_info = need_domain_info || hose->index;
hose->need_domain_info = need_domain_info; hose->need_domain_info = need_domain_info;
if (!bus) { next_busno = hose->bus->busn_res.end + 1;
pci_free_resource_list(&resources);
return;
}
next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose - /* Don't allow 8-bit bus number overflow inside the hose -
reserve some space for bridges. */ reserve some space for bridges. */
if (next_busno > 224) { if (next_busno > 224) {
...@@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose) ...@@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose)
need_domain_info = 1; need_domain_info = 1;
} }
pci_bus_size_bridges(bus); pci_bus_size_bridges(hose->bus);
pci_bus_assign_resources(bus); pci_bus_assign_resources(hose->bus);
pci_bus_add_devices(bus); pci_bus_add_devices(hose->bus);
} }
/* /*
...@@ -144,8 +155,6 @@ static int __init pcibios_init(void) ...@@ -144,8 +155,6 @@ static int __init pcibios_init(void)
for (hose = hose_head; hose; hose = hose->next) for (hose = hose_head; hose; hose = hose->next)
pcibios_scanbus(hose); pcibios_scanbus(hose);
pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
dma_debug_add_bus(&pci_bus_type); dma_debug_add_bus(&pci_bus_type);
pci_initialized = 1; pci_initialized = 1;
......
...@@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) ...@@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
return 0; 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); return evt2irq(0xae0);
} }
......
...@@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) ...@@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
{ {
LIST_HEAD(resources); LIST_HEAD(resources);
struct pci_bus *root_bus; 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, pci_add_resource_offset(&resources, &info->io_space,
info->io_space.start - 0x1000); info->io_space.start - 0x1000);
...@@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) ...@@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
info->busn.flags = IORESOURCE_BUS; info->busn.flags = IORESOURCE_BUS;
pci_add_resource(&resources, &info->busn); pci_add_resource(&resources, &info->busn);
root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, list_splice_init(&resources, &bridge->windows);
&resources); bridge->dev.parent = &ofdev->dev;
if (!root_bus) { bridge->sysdata = info;
pci_free_resource_list(&resources); 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; return;
} }
/* Setup IRQs of all devices using custom routines */ root_bus = bridge->bus;
pci_fixup_irqs(pci_common_swizzle, info->map_irq);
/* Assign devices with resources */ /* Assign devices with resources */
pci_assign_unassigned_resources(); pci_assign_unassigned_resources();
......
...@@ -274,6 +274,7 @@ static void fixup_read_and_payload_sizes(void) ...@@ -274,6 +274,7 @@ static void fixup_read_and_payload_sizes(void)
*/ */
int __init pcibios_init(void) int __init pcibios_init(void)
{ {
struct pci_host_bridge *bridge;
int i; int i;
pr_info("PCI: Probing PCI hardware\n"); pr_info("PCI: Probing PCI hardware\n");
...@@ -306,16 +307,26 @@ int __init pcibios_init(void) ...@@ -306,16 +307,26 @@ int __init pcibios_init(void)
pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &ioport_resource);
pci_add_resource(&resources, &iomem_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->root_bus = bus;
controller->last_busno = bus->busn_res.end; 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. * This comes from the generic Linux PCI driver.
* *
......
...@@ -669,6 +669,7 @@ int __init pcibios_init(void) ...@@ -669,6 +669,7 @@ int __init pcibios_init(void)
resource_size_t offset; resource_size_t offset;
LIST_HEAD(resources); LIST_HEAD(resources);
int next_busno; int next_busno;
struct pci_host_bridge *bridge;
int i; int i;
tile_pci_init(); tile_pci_init();
...@@ -881,15 +882,25 @@ int __init pcibios_init(void) ...@@ -881,15 +882,25 @@ int __init pcibios_init(void)
controller->mem_offset); controller->mem_offset);
pci_add_resource(&resources, &controller->io_space); pci_add_resource(&resources, &controller->io_space);
controller->first_busno = next_busno; 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; controller->root_bus = bus;
next_busno = bus->busn_res.end + 1; 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. * This comes from the generic Linux PCI driver.
* *
......
...@@ -101,7 +101,7 @@ void pci_puv3_preinit(void) ...@@ -101,7 +101,7 @@ void pci_puv3_preinit(void)
writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); 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) { if (dev->bus->number == 0) {
#ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */
...@@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus) ...@@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus)
} }
EXPORT_SYMBOL(pcibios_fixup_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) static int __init pci_common_init(void)
{ {
struct pci_bus *puv3_bus; 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(); 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) if (!puv3_bus)
panic("PCI: unable to scan 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_size_bridges(puv3_bus);
pci_bus_assign_resources(puv3_bus); pci_bus_assign_resources(puv3_bus);
pci_bus_add_devices(puv3_bus); pci_bus_add_devices(puv3_bus);
......
...@@ -17,12 +17,6 @@ ...@@ -17,12 +17,6 @@
#include <linux/cache.h> #include <linux/cache.h>
#include "pci.h" #include "pci.h"
void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
{
dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq);
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
void pci_assign_irq(struct pci_dev *dev) void pci_assign_irq(struct pci_dev *dev)
{ {
u8 pin; u8 pin;
...@@ -65,29 +59,5 @@ void pci_assign_irq(struct pci_dev *dev) ...@@ -65,29 +59,5 @@ void pci_assign_irq(struct pci_dev *dev)
/* Always tell the device, so the driver knows what is /* Always tell the device, so the driver knows what is
the real IRQ to use; the device does not use it. */ the real IRQ to use; the device does not use it. */
pcibios_update_irq(dev, irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
int (*map_irq)(const struct pci_dev *, u8, u8))
{
/*
* Implement pci_fixup_irqs() through pci_assign_irq().
* This code should be remove eventually, it is a wrapper
* around pci_assign_irq() interface to keep current
* pci_fixup_irqs() behaviour unchanged on architecture
* code still relying on its interface.
*/
struct pci_dev *dev = NULL;
struct pci_host_bridge *hbrg = NULL;
for_each_pci_dev(dev) {
hbrg = pci_find_host_bridge(dev->bus);
hbrg->swizzle_irq = swizzle;
hbrg->map_irq = map_irq;
pci_assign_irq(dev);
hbrg->swizzle_irq = NULL;
hbrg->map_irq = NULL;
}
} }
EXPORT_SYMBOL_GPL(pci_fixup_irqs);
...@@ -867,7 +867,6 @@ char *pcibios_setup(char *str); ...@@ -867,7 +867,6 @@ char *pcibios_setup(char *str);
resource_size_t pcibios_align_resource(void *, const struct resource *, resource_size_t pcibios_align_resource(void *, const struct resource *,
resource_size_t, resource_size_t,
resource_size_t); resource_size_t);
void pcibios_update_irq(struct pci_dev *, int irq);
/* Weak but can be overriden by arch */ /* Weak but can be overriden by arch */
void pci_fixup_cardbus(struct pci_bus *); void pci_fixup_cardbus(struct pci_bus *);
...@@ -1183,8 +1182,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus); ...@@ -1183,8 +1182,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
void pdev_enable_device(struct pci_dev *); void pdev_enable_device(struct pci_dev *);
int pci_enable_resources(struct pci_dev *, int mask); int pci_enable_resources(struct pci_dev *, int mask);
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
int (*)(const struct pci_dev *, u8, u8));
void pci_assign_irq(struct pci_dev *dev); void pci_assign_irq(struct pci_dev *dev);
struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res);
#define HAVE_PCI_REQ_REGIONS 2 #define HAVE_PCI_REQ_REGIONS 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment