aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2010-10-06 16:12:28 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2010-10-18 10:49:34 -0400
commit294ee6f89cfd629e276f632a6003a0fad7785dce (patch)
treed72a0ebf5fe371f22a9e8b7b24880d4758255121 /arch
parent1525bf0d8f059a38c6e79353583854e1981b2e67 (diff)
x86: Introduce x86_msi_ops
Introduce an x86 specific indirect mechanism to setup MSIs. The MSI setup functions become function pointers in an x86_msi_ops struct, that defaults to the implementation in io_apic.c and msi.c. [v2: Use HAVE_DEFAULT_* knobs] Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: x86@kernel.org Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/pci.h33
-rw-r--r--arch/x86/include/asm/x86_init.h9
-rw-r--r--arch/x86/kernel/apic/io_apic.c4
-rw-r--r--arch/x86/kernel/x86_init.c7
4 files changed, 49 insertions, 4 deletions
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index d395540ff894..ca0437c714b2 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -7,6 +7,7 @@
7#include <linux/string.h> 7#include <linux/string.h>
8#include <asm/scatterlist.h> 8#include <asm/scatterlist.h>
9#include <asm/io.h> 9#include <asm/io.h>
10#include <asm/x86_init.h>
10 11
11#ifdef __KERNEL__ 12#ifdef __KERNEL__
12 13
@@ -94,8 +95,36 @@ static inline void early_quirks(void) { }
94 95
95extern void pci_iommu_alloc(void); 96extern void pci_iommu_alloc(void);
96 97
97/* MSI arch hook */ 98#ifdef CONFIG_PCI_MSI
98#define arch_setup_msi_irqs arch_setup_msi_irqs 99/* MSI arch specific hooks */
100static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
101{
102 return x86_msi.setup_msi_irqs(dev, nvec, type);
103}
104
105static inline void x86_teardown_msi_irqs(struct pci_dev *dev)
106{
107 x86_msi.teardown_msi_irqs(dev);
108}
109
110static inline void x86_teardown_msi_irq(unsigned int irq)
111{
112 x86_msi.teardown_msi_irq(irq);
113}
114#define arch_setup_msi_irqs x86_setup_msi_irqs
115#define arch_teardown_msi_irqs x86_teardown_msi_irqs
116#define arch_teardown_msi_irq x86_teardown_msi_irq
117/* implemented in arch/x86/kernel/apic/io_apic. */
118int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
119void native_teardown_msi_irq(unsigned int irq);
120/* default to the implementation in drivers/lib/msi.c */
121#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
122void default_teardown_msi_irqs(struct pci_dev *dev);
123#else
124#define native_setup_msi_irqs NULL
125#define native_teardown_msi_irq NULL
126#define default_teardown_msi_irqs NULL
127#endif
99 128
100#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) 129#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
101 130
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index baa579c8e038..64642ad019fb 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -154,9 +154,18 @@ struct x86_platform_ops {
154 int (*i8042_detect)(void); 154 int (*i8042_detect)(void);
155}; 155};
156 156
157struct pci_dev;
158
159struct x86_msi_ops {
160 int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
161 void (*teardown_msi_irq)(unsigned int irq);
162 void (*teardown_msi_irqs)(struct pci_dev *dev);
163};
164
157extern struct x86_init_ops x86_init; 165extern struct x86_init_ops x86_init;
158extern struct x86_cpuinit_ops x86_cpuinit; 166extern struct x86_cpuinit_ops x86_cpuinit;
159extern struct x86_platform_ops x86_platform; 167extern struct x86_platform_ops x86_platform;
168extern struct x86_msi_ops x86_msi;
160 169
161extern void x86_init_noop(void); 170extern void x86_init_noop(void);
162extern void x86_init_uint_noop(unsigned int unused); 171extern void x86_init_uint_noop(unsigned int unused);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 44bb914a42b2..0885a4120737 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3330,7 +3330,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
3330 return 0; 3330 return 0;
3331} 3331}
3332 3332
3333int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3333int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3334{ 3334{
3335 int node, ret, sub_handle, index = 0; 3335 int node, ret, sub_handle, index = 0;
3336 unsigned int irq, irq_want; 3336 unsigned int irq, irq_want;
@@ -3388,7 +3388,7 @@ error:
3388 return ret; 3388 return ret;
3389} 3389}
3390 3390
3391void arch_teardown_msi_irq(unsigned int irq) 3391void native_teardown_msi_irq(unsigned int irq)
3392{ 3392{
3393 destroy_irq(irq); 3393 destroy_irq(irq);
3394} 3394}
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index cd6da6bf3eca..ceb2911aa439 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -6,10 +6,12 @@
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/ioport.h> 7#include <linux/ioport.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/pci.h>
9 10
10#include <asm/bios_ebda.h> 11#include <asm/bios_ebda.h>
11#include <asm/paravirt.h> 12#include <asm/paravirt.h>
12#include <asm/pci_x86.h> 13#include <asm/pci_x86.h>
14#include <asm/pci.h>
13#include <asm/mpspec.h> 15#include <asm/mpspec.h>
14#include <asm/setup.h> 16#include <asm/setup.h>
15#include <asm/apic.h> 17#include <asm/apic.h>
@@ -99,3 +101,8 @@ struct x86_platform_ops x86_platform = {
99}; 101};
100 102
101EXPORT_SYMBOL_GPL(x86_platform); 103EXPORT_SYMBOL_GPL(x86_platform);
104struct x86_msi_ops x86_msi = {
105 .setup_msi_irqs = native_setup_msi_irqs,
106 .teardown_msi_irq = native_teardown_msi_irq,
107 .teardown_msi_irqs = default_teardown_msi_irqs,
108};