I'm rewriting the Alchemy PCI driver to be a platform driver, and
one thing that bugs me to no end is that for every PCI controller
the same global pcibios_map_irq function is called.
Instead I'd like to pass the per-board pci irq tables through
platform data and provide a per-controller map_irq callback.
This patch adds a maq_irq callback to struct pci_controller,
and uses it if available in pcibios_init().
Run-tested on a DB1500 board.
Comments welcome!
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
Eventually I'd like to do this also with pcibios_plat_dev_init,
which is unused except on octeon and SSB-bus BCM chips.
arch/mips/alchemy/common/pci.c | 8 ++++++++
arch/mips/alchemy/devboards/db1x00/board_setup.c | 8 ++++----
arch/mips/include/asm/pci.h | 2 ++
arch/mips/pci/fixup-au1000.c | 4 +---
arch/mips/pci/pci.c | 9 ++++++---
5 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/arch/mips/alchemy/common/pci.c b/arch/mips/alchemy/common/pci.c
index 7866cf5..e7bd034 100644
--- a/arch/mips/alchemy/common/pci.c
+++ b/arch/mips/alchemy/common/pci.c
@@ -53,10 +53,18 @@ static struct resource pci_mem_resource = {
extern struct pci_ops au1x_pci_ops;
+extern char irq_tab_alchemy[][5];
+
+int alchemy_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_alchemy[slot][pin];
+}
+
static struct pci_controller au1x_controller = {
.pci_ops = &au1x_pci_ops,
.io_resource = &pci_io_resource,
.mem_resource = &pci_mem_resource,
+ .map_irq = alchemy_pci_map_irq,
};
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c
b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index 5c956fe..8f6b926 100644
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -41,7 +41,7 @@
#include <prom.h>
#ifdef CONFIG_MIPS_DB1500
-char irq_tab_alchemy[][5] __initdata = {
+char irq_tab_alchemy[][5] = {
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371
*/
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC,
AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
@@ -50,7 +50,7 @@ char irq_tab_alchemy[][5] __initdata = {
#ifdef CONFIG_MIPS_DB1550
-char irq_tab_alchemy[][5] __initdata = {
+char irq_tab_alchemy[][5] = {
[11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 -
on-board HPT371 */
[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD,
AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC,
AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
@@ -59,7 +59,7 @@ char irq_tab_alchemy[][5] __initdata = {
#ifdef CONFIG_MIPS_BOSPORUS
-char irq_tab_alchemy[][5] __initdata = {
+char irq_tab_alchemy[][5] = {
[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL
11 - miniPCI */
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741
*/
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC,
AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
@@ -91,7 +91,7 @@ const char *get_system_type(void)
#ifdef CONFIG_MIPS_MIRAGE
-char irq_tab_alchemy[][5] __initdata = {
+char irq_tab_alchemy[][5] = {
[11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX
*/
[12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300
*/
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL
13 - miniPCI */
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 576397c..a5d30ef 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -45,6 +45,8 @@ struct pci_controller {
of the PCI controller */
int (*get_busno)(void);
void (*set_busno)(int busno);
+
+ int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
};
/*
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index e2ddfc4..448d8e5 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -29,11 +29,9 @@
#include <linux/pci.h>
#include <linux/init.h>
-extern char irq_tab_alchemy[][5];
-
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- return irq_tab_alchemy[slot][pin];
+ return -1;
}
/* Do platform specific device initialization at pci_enable_device() time */
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 33bba7b..74f62e4 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -154,10 +154,13 @@ static int __init pcibios_init(void)
struct pci_controller *hose;
/* Scan all of the recorded PCI controllers. */
- for (hose = hose_head; hose; hose = hose->next)
+ for (hose = hose_head; hose; hose = hose->next) {
pcibios_scanbus(hose);
-
- pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
+ if (hose->map_irq)
+ pci_fixup_irqs(pci_common_swizzle, hose->map_irq);
+ else
+ pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
+ }
pci_initialized = 1;
--
1.7.6
|