x86/apic changes for v3.3
Subsystems (8)
Linus,
Please pull the latest x86-apic-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-apic-for-linus
out-of-topic modifications in x86-apic-for-linus:
-------------------------------------------------
drivers/edac/sb_edac.c # 141168c: x86: Simplify code by removing a drivers/hwmon/coretemp.c # 141168c: x86: Simplify code by removing a drivers/pci/Kconfig # b95a7bd: pci, x86/io-apic: Allow PCI_IOAPI drivers/pci/ioapic.c # b95a7bd: pci, x86/io-apic: Allow PCI_IOAPI
Thanks,
Ingo
------------------>
Daniel J Blueman (2):
x86: Make flat_init_apic_ldr() available
x86: Add x86_init platform override to fix up NUMA core numbering
Fernando Luis Vazquez Cao (1):
x86: Convert per-cpu counter icr_read_retry_count into a member of irq_stat
Fernando Luis Vázquez Cao (1):
x86: Add per-cpu stat counter for APIC ICR read tries
Jan Beulich (1):
pci, x86/io-apic: Allow PCI_IOAPIC to be user configurable on x86
Kevin Winchester (1):
x86: Simplify code by removing a !SMP #ifdefs from 'struct cpuinfo_x86'
Steffen Persvold (2):
x86: Add NumaChip support
x86: Fix the !CONFIG_NUMA build of the new CPU ID fixup code support
Suresh Siddha (1):
x86: Skip cpus with apic-ids >= 255 in !x2apic_mode
Yinghai Lu (4):
x86, apic: Add probe() for apic_flat
x86, acpi: Skip acpi x2apic entries if the x2apic feature is not present x86, x2apic: Fallback to xapic when BIOS doesn't setup interrupt-remapping x86, x2apic: Allow "nox2apic" to disable x2apic mode setup by BIOS
arch/x86/Kconfig | 13 ++ arch/x86/include/asm/apic.h | 6 + arch/x86/include/asm/apic_flat_64.h | 7 + arch/x86/include/asm/apicdef.h | 1 + arch/x86/include/asm/hardirq.h | 1 + arch/x86/include/asm/numachip/numachip_csr.h | 167 +++++++++++++++ arch/x86/include/asm/processor.h | 2 - arch/x86/include/asm/x86_init.h | 3 + arch/x86/kernel/acpi/boot.c | 10 +- arch/x86/kernel/amd_nb.c | 8 +- arch/x86/kernel/apic/Makefile | 1 + arch/x86/kernel/apic/apic.c | 107 +++++++--- arch/x86/kernel/apic/apic_flat_64.c | 9 +- arch/x86/kernel/apic/apic_numachip.c | 294 ++++++++++++++++++++++++++ arch/x86/kernel/apic/io_apic.c | 4 + arch/x86/kernel/cpu/amd.c | 9 +- arch/x86/kernel/cpu/common.c | 14 +- arch/x86/kernel/cpu/intel.c | 2 - arch/x86/kernel/cpu/mcheck/mce.c | 2 - arch/x86/kernel/cpu/mcheck/mce_amd.c | 7 +- arch/x86/kernel/cpu/proc.c | 4 +- arch/x86/kernel/irq.c | 5 + arch/x86/kernel/smpboot.c | 3 +- arch/x86/kernel/x86_init.c | 1 + arch/x86/mm/srat.c | 7 +- drivers/edac/sb_edac.c | 2 - drivers/hwmon/coretemp.c | 7 +- drivers/pci/Kconfig | 4 +- drivers/pci/ioapic.c | 15 +- 29 files changed, 639 insertions(+), 76 deletions(-) create mode 100644 arch/x86/include/asm/apic_flat_64.h create mode 100644 arch/x86/include/asm/numachip/numachip_csr.h create mode 100644 arch/x86/kernel/apic/apic_numachip.c
arch/x86/Kconfig +13 -0
@@ -343,6 +343,7 @@ config X86_EXTENDED_PLATFORM If you enable this option then you'll be able to select support for the following (non-PC) 64 bit x86 platforms: + Numascale NumaChip ScaleMP vSMP SGI Ultraviolet
@@ -351,6 +352,18 @@ config X86_EXTENDED_PLATFORM endif # This is an alphabetically sorted list of 64 bit extended platforms # Please maintain the alphabetic order if and when there are additions +config X86_NUMACHIP + bool "Numascale NumaChip" + depends on X86_64 + depends on X86_EXTENDED_PLATFORM + depends on NUMA + depends on SMP + depends on X86_X2APIC + depends on !EDAC_AMD64 + ---help--- + Adds support for Numascale NumaChip large-SMP systems. Needed to + enable more than ~168 cores. + If you don't have one of these, you should say N here. config X86_VSMP bool "ScaleMP vSMP"
arch/x86/include/asm/apic.h +6 -0
@@ -176,6 +176,7 @@ static inline u64 native_x2apic_icr_read(void) }extern int x2apic_phys; +extern int x2apic_preenabled;extern void check_x2apic (void );extern void enable_x2apic (void );extern void x2apic_icr_write (u32 low,u32 id);
@@ -198,6 +199,9 @@ static inline void x2apic_force_phys(void) x2apic_phys = 1; }#else +static inline void disable_x2apic (void ) +{ +}static inline void check_x2apic (void ) { }
@@ -212,6 +216,7 @@ static inline void x2apic_force_phys(void) { } +#define nox2apic 0#define x2apic_preenabled 0#define x2apic_supported () 0#endif
@@ -410,6 +415,7 @@ extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);#endif #ifdef CONFIG_X86_LOCAL_APIC +static inline u32 apic_read (u32 reg) {return apic->read (reg);
arch/x86/include/asm/apic_flat_64.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef _ASM_X86_APIC_FLAT_64_H +#define _ASM_X86_APIC_FLAT_64_H + +extern void flat_init_apic_ldr (void ); + +#endif +
arch/x86/include/asm/apicdef.h +1 -0
@@ -144,6 +144,7 @@#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))#define APIC_BASE_MSR 0x800 +#define XAPIC_ENABLE (1UL << 11)#define X2APIC_ENABLE (1UL << 10)#ifdef CONFIG_X86_32
arch/x86/include/asm/hardirq.h +1 -0
@@ -11,6 +11,7 @@ typedef struct {#ifdef CONFIG_X86_LOCAL_APIC unsigned int apic_timer_irqs;/* arch dependent */ unsigned int irq_spurious_count; +unsigned int icr_read_retry_count;#endif unsigned int x86_platform_ipis;/* arch dependent */ unsigned int apic_perf_irqs;
arch/x86/include/asm/numachip/numachip_csr.h new file +167 -0
167 lines not on this page · raw message
arch/x86/include/asm/processor.h +0 -2
@@ -99,7 +99,6 @@ struct cpuinfo_x86 {u16 apicid;u16 initial_apicid;u16 x86_clflush_size; -#ifdef CONFIG_SMP /* number of cores as seen by the OS: */ u16 booted_cores;/* Physical processor id: */
@@ -110,7 +109,6 @@ struct cpuinfo_x86 {u8 compute_unit_id;/* Index into per_cpu list: */ u16 cpu_index; -#endif u32 microcode; } __attribute__((__aligned__(SMP_CACHE_BYTES)));
arch/x86/include/asm/x86_init.h +3 -0
@@ -7,6 +7,7 @@struct mpc_bus ;struct mpc_cpu ;struct mpc_table ; +struct cpuinfo_x86 ;/** * struct x86_init_mpparse - platform specific mpparse ops
@@ -147,6 +148,7 @@ struct x86_init_ops {*/ struct x86_cpuinit_ops {void (*setup_percpu_clockev)(void ); +void (*fixup_cpu_id)(struct cpuinfo_x86 *c,int node); };/**
@@ -186,5 +188,6 @@ extern struct x86_msi_ops x86_msi;extern void x86_init_noop (void );extern void x86_init_uint_noop (unsigned int unused); +extern void x86_default_fixup_cpu_id (struct cpuinfo_x86 *c,int node);#endif
arch/x86/kernel/acpi/boot.c +8 -2
@@ -219,6 +219,8 @@ static int __init acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) {struct acpi_madt_local_x2apic *processor =NULL ; +int apic_id; +u8 enabled; processor = (struct acpi_madt_local_x2apic *)header;
@@ -227,6 +229,8 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)acpi_table_print_madt_entry (header); + apic_id = processor->local_apic_id; + enabled = processor->lapic_flags &ACPI_MADT_ENABLED ;#ifdef CONFIG_X86_X2APIC /* * We need to register disabled CPU as well to permit
@@ -235,8 +239,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -acpi_register_lapic (processor->local_apic_id,/* APIC ID */ - processor->lapic_flags &ACPI_MADT_ENABLED ); +if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +else +acpi_register_lapic (apic_id, enabled);#else printk(KERN_WARNING PREFIX "x2apic entry ignored\n");#endif
arch/x86/kernel/amd_nb.c +2 -6
@@ -123,16 +123,14 @@ int amd_get_subcaches(int cpu) {struct pci_dev *link =node_to_amd_nb (amd_get_nb_id (cpu))->link;unsigned int mask; -int cuid =0 ; +int cuid;if (!amd_nb_has_feature (AMD_NB_L3_PARTITIONING ))return 0 ;pci_read_config_dword (link,0x1d4 , &mask); -#ifdef CONFIG_SMP cuid =cpu_data (cpu).compute_unit_id; -#endif return (mask >> (4 * cuid)) &0xf ; }
@@ -141,7 +139,7 @@ int amd_set_subcaches(int cpu, int mask)static unsigned int reset, ban;struct amd_northbridge *nb =node_to_amd_nb (amd_get_nb_id (cpu));unsigned int reg; -int cuid =0 ; +int cuid;if (!amd_nb_has_feature (AMD_NB_L3_PARTITIONING ) || mask >0xf )return -EINVAL ;
@@ -159,9 +157,7 @@ int amd_set_subcaches(int cpu, int mask)pci_write_config_dword (nb->misc,0x1b8 , reg & ~0x180000 ); } -#ifdef CONFIG_SMP cuid =cpu_data (cpu).compute_unit_id; -#endif mask <<=4 * cuid; mask |= (0xf ^ (1 << cuid)) <<26 ;
arch/x86/kernel/apic/Makefile +1 -0
@@ -10,6 +10,7 @@ obj-$(CONFIG_SMP) += ipi.o ifeq ($(CONFIG_X86_64),y) # APIC probe will depend on the listing order here +obj-$(CONFIG_X86_NUMACHIP) += apic_numachip.o obj-$(CONFIG_X86_UV) += x2apic_uv_x.o obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o
arch/x86/kernel/apic/apic.c +81 -26
179 lines not on this page · raw message
arch/x86/kernel/apic/apic_flat_64.c +7 -2
@@ -62,7 +62,7 @@ static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask)* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel * document number 292116). So here it goes... */ -static void flat_init_apic_ldr (void ) +void flat_init_apic_ldr (void ) {unsigned long val;unsigned long num, id;
@@ -171,9 +171,14 @@ static int flat_phys_pkg_id(int initial_apic_id, int index_msb)return initial_apic_id >> index_msb; } +static int flat_probe (void ) +{ +return 1 ; +} +static struct apic apic_flat = { .name ="flat" , - .probe =NULL , + .probe = flat_probe, .acpi_madt_oem_check = flat_acpi_madt_oem_check, .apic_id_registered = flat_apic_id_registered,
arch/x86/kernel/apic/apic_numachip.c new file +294 -0
294 lines not on this page · raw message
arch/x86/kernel/apic/io_apic.c +4 -0
@@ -2948,6 +2948,10 @@ static inline void __init check_timer(void) }local_irq_disable ();apic_printk (APIC_QUIET ,KERN_INFO "..... failed :(.\n" ); +if (x2apic_preenabled) +apic_printk (APIC_QUIET ,KERN_INFO +"Perhaps problem with the pre-enabled x2apic mode\n" +"Try booting with x2apic and interrupt-remapping disabled in the bios.\n" );panic ("IO-APIC + timer doesn't work! Boot with apic=debug and send a " "report. Then try booting with the 'noapic' option.\n" ); out:
arch/x86/kernel/cpu/amd.c +7 -2
@@ -148,7 +148,6 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)static void __cpuinit amd_k7_smp_check (struct cpuinfo_x86 *c) { -#ifdef CONFIG_SMP /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index)return ;
@@ -192,7 +191,6 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c) valid_k7: ; -#endif }static void __cpuinit init_amd_k7 (struct cpuinfo_x86 *c)
@@ -353,6 +351,13 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)if (node ==NUMA_NO_NODE ) node =per_cpu (cpu_llc_id, cpu); +/* +* If core numbers are inconsistent, it's likely a multi-fabric platform, +* so invoke platform-specific handler +*/ +if (c->phys_proc_id != node) + x86_cpuinit.fixup_cpu_id (c, node); +if (!node_online (node)) {/* * Two possibilities here:
arch/x86/kernel/cpu/common.c +9 -5
@@ -676,9 +676,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)if (this_cpu->c_early_init) this_cpu->c_early_init (c); -#ifdef CONFIG_SMP c->cpu_index =0 ; -#endif filter_cpuid_features (c, false);setup_smep (c);
@@ -764,10 +762,7 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) c->apicid = c->initial_apicid;# endif #endif - -#ifdef CONFIG_X86_HT c->phys_proc_id = c->initial_apicid; -#endif }setup_smep (c);
@@ -1141,6 +1136,15 @@ static void dbg_restore_debug_regs(void)#endif /* ! CONFIG_KGDB */ /* +* Prints an error where the NUMA and configured core-number mismatch and the +* platform didn't override this to fix it up +*/ +void __cpuinit x86_default_fixup_cpu_id (struct cpuinfo_x86 *c,int node) +{ +pr_err ("NUMA core number %d differs from configured core number %d\n" , node, c->phys_proc_id); +} + +/* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT * and IDT. We reload them nevertheless, this function acts as a
arch/x86/kernel/cpu/intel.c +0 -2
@@ -181,7 +181,6 @@ static void __cpuinit trap_init_f00f_bug(void)static void __cpuinit intel_smp_check (struct cpuinfo_x86 *c) { -#ifdef CONFIG_SMP /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index)return ;
@@ -198,7 +197,6 @@ static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)WARN_ONCE (1 ,"WARNING: SMP operation may be unreliable" "with B stepping processors.\n" ); } -#endif }static void __cpuinit intel_workarounds (struct cpuinfo_x86 *c)
arch/x86/kernel/cpu/mcheck/mce.c +0 -2
@@ -119,9 +119,7 @@ void mce_setup(struct mce *m) m->time =get_seconds (); m->cpuvendor = boot_cpu_data.x86_vendor; m->cpuid =cpuid_eax (1 ); -#ifdef CONFIG_SMP m->socketid =cpu_data (m->extcpu).phys_proc_id; -#endif m->apicid =cpu_data (m->extcpu).initial_apicid;rdmsrl (MSR_IA32_MCG_CAP , m->mcgcap); }
arch/x86/kernel/cpu/mcheck/mce_amd.c +1 -6
@@ -64,11 +64,9 @@ struct threshold_bank { }; static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); -#ifdef CONFIG_SMP static unsigned char shared_bank[NR_BANKS ] = {0 ,0 ,0 ,0 ,1 }; -#endif static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
@@ -202,10 +200,9 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)if (!block)per_cpu (bank_map, cpu) |= (1 << bank); -#ifdef CONFIG_SMP if (shared_bank[bank] && c->cpu_core_id)break ; -#endif + offset =setup_APIC_mce (offset, (high &MASK_LVTOFF_HI ) >>20 );
@@ -531,7 +528,6 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)sprintf (name,"threshold_bank%i" , bank); -#ifdef CONFIG_SMP if (cpu_data (cpu).cpu_core_id && shared_bank[bank]) {/* symlink */ i =cpumask_first (cpu_llc_shared_mask (cpu));
@@ -558,7 +554,6 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) goto out; } -#endif b =kzalloc (sizeof (struct threshold_bank ),GFP_KERNEL );if (!b) {
arch/x86/kernel/cpu/proc.c +1 -3
@@ -64,12 +64,10 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)static int show_cpuinfo (struct seq_file *m,void *v) {struct cpuinfo_x86 *c = v; -unsigned int cpu =0 ; +unsigned int cpu;int i; -#ifdef CONFIG_SMP cpu = c->cpu_index; -#endif seq_printf (m,"processor\t: %u\n" "vendor_id\t: %s\n" "cpu family\t: %d\n"
arch/x86/kernel/irq.c +5 -0
@@ -74,6 +74,10 @@ int arch_show_interrupts(struct seq_file *p, int prec)for_each_online_cpu (j)seq_printf (p,"%10u " ,irq_stats (j)->apic_irq_work_irqs);seq_printf (p," IRQ work interrupts\n" ); +seq_printf (p,"%*s: " , prec,"RTR" ); +for_each_online_cpu (j) +seq_printf (p,"%10u " ,irq_stats (j)->icr_read_retry_count); +seq_printf (p," APIC ICR read retries\n" );#endif if (x86_platform_ipi_callback) {seq_printf (p,"%*s: " , prec,"PLT" );
@@ -136,6 +140,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum +=irq_stats (cpu)->irq_spurious_count; sum +=irq_stats (cpu)->apic_perf_irqs; sum +=irq_stats (cpu)->apic_irq_work_irqs; + sum +=irq_stats (cpu)->icr_read_retry_count;#endif if (x86_platform_ipi_callback) sum +=irq_stats (cpu)->x86_platform_ipis;
arch/x86/kernel/smpboot.c +2 -1
@@ -840,7 +840,8 @@ int __cpuinit native_cpu_up(unsigned int cpu)pr_debug ("++++++++++++++++++++=_---CPU UP %u\n" , cpu);if (apicid ==BAD_APICID || apicid == boot_cpu_physical_apicid || - !physid_isset (apicid, phys_cpu_present_map)) { + !physid_isset (apicid, phys_cpu_present_map) || + (!x2apic_mode && apicid >=255 )) {printk (KERN_ERR "%s: bad cpu %d\n" , __func__, cpu);return -EINVAL ; }
arch/x86/kernel/x86_init.c +1 -0
@@ -92,6 +92,7 @@ struct x86_init_ops x86_init __initdata = {struct x86_cpuinit_ops x86_cpuinit__cpuinitdata = { .setup_percpu_clockev = setup_secondary_APIC_clock, + .fixup_cpu_id = x86_default_fixup_cpu_id, };static void default_nmi_init (void ) { };
arch/x86/mm/srat.c +6 -1
@@ -69,6 +69,12 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; + apic_id = pa->apic_id; +if (!cpu_has_x2apic && (apic_id >=0xff )) { +printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , + pxm, apic_id); +return ; + } node =setup_node (pxm);if (node <0 ) {printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm);
@@ -76,7 +82,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; } - apic_id = pa->apic_id;if (apic_id >=MAX_LOCAL_APIC ) {printk (KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n" , pxm, apic_id, node);return ;
drivers/edac/sb_edac.c +0 -2
@@ -1609,11 +1609,9 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, mce->cpuvendor, mce->cpuid, mce->time, mce->socketid, mce->apicid); -#ifdef CONFIG_SMP /* Only handle if it is the right mc controller */ if (cpu_data (mce->cpu).phys_proc_id != pvt->sbridge_dev->mc)return NOTIFY_DONE ; -#endif smp_rmb ();if ((pvt->mce_out +1 ) %MCE_LOG_LEN == pvt->mce_in) {
drivers/hwmon/coretemp.c +3 -4
@@ -57,16 +57,15 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)#define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -#ifdef CONFIG_SMP #define TO_PHYS_ID (cpu) cpu_data(cpu).phys_proc_id#define TO_CORE_ID (cpu) cpu_data(cpu).cpu_core_id +#define TO_ATTR_NO (cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) + +#ifdef CONFIG_SMP #define for_each_sibling (i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu))#else -#define TO_PHYS_ID (cpu) (cpu) -#define TO_CORE_ID (cpu) (cpu)#define for_each_sibling (i, cpu) for (i = 0; false; )#endif -#define TO_ATTR_NO (cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)/* * Per-Core Temperature Data
drivers/pci/Kconfig +2 -2
@@ -98,11 +98,11 @@ config PCI_PASID If unsure, say N. config PCI_IOAPIC - bool + tristate "PCI IO-APIC hotplug support" if X86 depends on PCI depends on ACPI depends on HOTPLUG - default y + default !X86 config PCI_LABEL def_bool y if (DMI || ACPI)
drivers/pci/ioapic.c +7 -8
@@ -17,7 +17,7 @@*/ #include <linux/pci.h> -#include <linux/export.h> +#include <linux/module.h> #include <linux/acpi.h> #include <linux/slab.h> #include <acpi/acpi_bus.h>
@@ -27,7 +27,7 @@ struct ioapic {u32 gsi_base; }; -static int ioapic_probe (struct pci_dev *dev,const struct pci_device_id *ent) +static int __devinit ioapic_probe (struct pci_dev *dev,const struct pci_device_id *ent) {acpi_handle handle;acpi_status status;
@@ -88,7 +88,7 @@ exit_free:return -ENODEV ; } -static void ioapic_remove (struct pci_dev *dev) +static void __devexit ioapic_remove(struct pci_dev *dev) {struct ioapic *ioapic =pci_get_drvdata (dev);
@@ -99,13 +99,12 @@ static void ioapic_remove(struct pci_dev *dev) } -static struct pci_device_id ioapic_devices[] = { - {PCI_ANY_ID ,PCI_ANY_ID ,PCI_ANY_ID ,PCI_ANY_ID , -PCI_CLASS_SYSTEM_PIC_IOAPIC <<8 ,0xffff00 , }, - {PCI_ANY_ID ,PCI_ANY_ID ,PCI_ANY_ID ,PCI_ANY_ID , -PCI_CLASS_SYSTEM_PIC_IOXAPIC <<8 ,0xffff00 , }, +static DEFINE_PCI_DEVICE_TABLE (ioapic_devices) = { + {PCI_DEVICE_CLASS (PCI_CLASS_SYSTEM_PIC_IOAPIC , ~0 ) }, + {PCI_DEVICE_CLASS (PCI_CLASS_SYSTEM_PIC_IOXAPIC , ~0 ) }, { } }; +MODULE_DEVICE_TABLE (pci, ioapic_devices);static struct pci_driver ioapic_driver = { .name ="ioapic" ,