Skip to content

Commit

Permalink
[ARM] Orion: fix ->map_irq() PCIe bus number check
Browse files Browse the repository at this point in the history
The current orion5x board ->map_irq() routines check whether a
given bus number lives on the PCIe controller by comparing it with
the PCIe controller's primary bus number.  This doesn't work in
case there are multiple buses in the PCIe domain, i.e. if there
exists a PCIe bridge on the primary PCIe bus.

This patch adds a helper function (orion5x_pci_map_irq()) that
returns the IRQ number for the given PCI device if that device has
a hard-wired IRQ, or -1 otherwise, and makes each board's
->map_irq() function use this helper function.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: Nicolas Pitre <nico@marvell.com>
  • Loading branch information
Lennert Buytenhek authored and Nicolas Pitre committed Apr 28, 2008
1 parent fd153ab commit 92b913b
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 27 deletions.
3 changes: 1 addition & 2 deletions arch/arm/mach-orion5x/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ struct pci_sys_data;
struct pci_bus;

void orion5x_pcie_id(u32 *dev, u32 *rev);
int orion5x_pcie_local_bus_nr(void);
int orion5x_pci_local_bus_nr(void);
int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys);
struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);

/*
* Valid GPIO pins according to MPP setup, used by machine-setup.
Expand Down
11 changes: 7 additions & 4 deletions arch/arm/mach-orion5x/db88f5281-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,17 @@ void __init db88f5281_pci_preinit(void)

static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;

/*
* PCIE IRQ is connected internally (not GPIO)
* Check for devices with hard-wired IRQs.
*/
if (dev->bus->number == orion5x_pcie_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;

/*
* PCI IRQs are connected via GPIOs
* PCI IRQs are connected via GPIOs.
*/
switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
case 0:
Expand Down
13 changes: 9 additions & 4 deletions arch/arm/mach-orion5x/dns323-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@

static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
/* PCI-E */
if (dev->bus->number == orion5x_pcie_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
int irq;

pr_err("%s: requested mapping for unknown bus\n", __func__);
/*
* Check for devices with hard-wired IRQs.
*/
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;

pr_err("%s: requested mapping for unknown device\n", __func__);

return -1;
}
Expand Down
14 changes: 10 additions & 4 deletions arch/arm/mach-orion5x/kurobox_pro-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,19 @@ static struct platform_device kurobox_pro_nor_flash = {

static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;

/*
* Check for devices with hard-wired IRQs.
*/
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;

/*
* PCI isn't used on the Kuro
*/
if (dev->bus->number == orion5x_pcie_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
else
printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");
printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");

return -1;
}
Expand Down
20 changes: 14 additions & 6 deletions arch/arm/mach-orion5x/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ void __init orion5x_pcie_id(u32 *dev, u32 *rev)
*rev = orion_pcie_rev(PCIE_BASE);
}

int __init orion5x_pcie_local_bus_nr(void)
{
return orion_pcie_get_local_bus_nr(PCIE_BASE);
}

static int pcie_valid_config(int bus, int dev)
{
/*
Expand Down Expand Up @@ -269,7 +264,7 @@ static int __init pcie_setup(struct pci_sys_data *sys)
*/
static DEFINE_SPINLOCK(orion5x_pci_lock);

int orion5x_pci_local_bus_nr(void)
static int orion5x_pci_local_bus_nr(void)
{
u32 conf = orion5x_read(PCI_P2P_CONF);
return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
Expand Down Expand Up @@ -557,3 +552,16 @@ struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys

return bus;
}

int __init orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int bus = dev->bus->number;

/*
* PCIe endpoint?
*/
if (bus < orion5x_pci_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;

return -1;
}
9 changes: 6 additions & 3 deletions arch/arm/mach-orion5x/rd88f5182-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,14 @@ void __init rd88f5182_pci_preinit(void)

static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;

/*
* PCI-E isn't used on the RD2
* Check for devices with hard-wired IRQs.
*/
if (dev->bus->number == orion5x_pcie_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;

/*
* PCI IRQs are connected via GPIOs
Expand Down
11 changes: 7 additions & 4 deletions arch/arm/mach-orion5x/ts209-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,17 @@ void __init qnap_ts209_pci_preinit(void)

static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;

/*
* PCIE IRQ is connected internally (not GPIO)
* Check for devices with hard-wired IRQs.
*/
if (dev->bus->number == orion5x_pcie_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;

/*
* PCI IRQs are connected via GPIOs
* PCI IRQs are connected via GPIOs.
*/
switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
case 0:
Expand Down

0 comments on commit 92b913b

Please sign in to comment.