aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/irq_remapping.h9
-rw-r--r--arch/x86/kernel/early-quirks.c20
2 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 95fd3527f632..d806b228d2c0 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -24,10 +24,18 @@
24 24
25#include <asm/io_apic.h> 25#include <asm/io_apic.h>
26 26
27struct IO_APIC_route_entry;
28struct io_apic_irq_attr;
29struct irq_chip;
30struct msi_msg;
31struct pci_dev;
32struct irq_cfg;
33
27#ifdef CONFIG_IRQ_REMAP 34#ifdef CONFIG_IRQ_REMAP
28 35
29extern void setup_irq_remapping_ops(void); 36extern void setup_irq_remapping_ops(void);
30extern int irq_remapping_supported(void); 37extern int irq_remapping_supported(void);
38extern void set_irq_remapping_broken(void);
31extern int irq_remapping_prepare(void); 39extern int irq_remapping_prepare(void);
32extern int irq_remapping_enable(void); 40extern int irq_remapping_enable(void);
33extern void irq_remapping_disable(void); 41extern void irq_remapping_disable(void);
@@ -54,6 +62,7 @@ void irq_remap_modify_chip_defaults(struct irq_chip *chip);
54 62
55static inline void setup_irq_remapping_ops(void) { } 63static inline void setup_irq_remapping_ops(void) { }
56static inline int irq_remapping_supported(void) { return 0; } 64static inline int irq_remapping_supported(void) { return 0; }
65static inline void set_irq_remapping_broken(void) { }
57static inline int irq_remapping_prepare(void) { return -ENODEV; } 66static inline int irq_remapping_prepare(void) { return -ENODEV; }
58static inline int irq_remapping_enable(void) { return -ENODEV; } 67static inline int irq_remapping_enable(void) { return -ENODEV; }
59static inline void irq_remapping_disable(void) { } 68static inline void irq_remapping_disable(void) { }
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 3755ef494390..94ab6b90dd3f 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -18,6 +18,7 @@
18#include <asm/apic.h> 18#include <asm/apic.h>
19#include <asm/iommu.h> 19#include <asm/iommu.h>
20#include <asm/gart.h> 20#include <asm/gart.h>
21#include <asm/irq_remapping.h>
21 22
22static void __init fix_hypertransport_config(int num, int slot, int func) 23static void __init fix_hypertransport_config(int num, int slot, int func)
23{ 24{
@@ -192,6 +193,21 @@ static void __init ati_bugs_contd(int num, int slot, int func)
192} 193}
193#endif 194#endif
194 195
196static void __init intel_remapping_check(int num, int slot, int func)
197{
198 u8 revision;
199
200 revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
201
202 /*
203 * Revision 0x13 of this chipset supports irq remapping
204 * but has an erratum that breaks its behavior, flag it as such
205 */
206 if (revision == 0x13)
207 set_irq_remapping_broken();
208
209}
210
195#define QFLAG_APPLY_ONCE 0x1 211#define QFLAG_APPLY_ONCE 0x1
196#define QFLAG_APPLIED 0x2 212#define QFLAG_APPLIED 0x2
197#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) 213#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -221,6 +237,10 @@ static struct chipset early_qrk[] __initdata = {
221 PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs }, 237 PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
222 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, 238 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
223 PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd }, 239 PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
240 { PCI_VENDOR_ID_INTEL, 0x3403, PCI_CLASS_BRIDGE_HOST,
241 PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
242 { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
243 PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
224 {} 244 {}
225}; 245};
226 246