This will pave the way for each apic driver to be self-contained and eliminate the need for apic_probe[]. Order in which apic drivers are listed in the .apicdrivers section is important, as this determines the apic probe order. And this is enforced by the ordering of apic driver files in the Makefile and the macros apic_driver()/apic_drivers(). Signed-off-by: Suresh Siddha --- arch/x86/include/asm/apic.h | 20 ++++++++++++++++++++ arch/x86/kernel/apic/Makefile | 17 +++++++++++------ arch/x86/kernel/apic/apic_flat_64.c | 5 +++++ arch/x86/kernel/apic/bigsmp_32.c | 2 ++ arch/x86/kernel/apic/es7000_32.c | 6 ++++++ arch/x86/kernel/apic/numaq_32.c | 2 ++ arch/x86/kernel/apic/probe_32.c | 2 ++ arch/x86/kernel/apic/summit_32.c | 2 ++ arch/x86/kernel/apic/x2apic_cluster.c | 2 ++ arch/x86/kernel/apic/x2apic_phys.c | 2 ++ arch/x86/kernel/apic/x2apic_uv_x.c | 2 ++ arch/x86/kernel/vmlinux.lds.S | 7 +++++++ 12 files changed, 63 insertions(+), 6 deletions(-) Index: linux-2.6-tip/arch/x86/include/asm/apic.h =================================================================== --- linux-2.6-tip.orig/arch/x86/include/asm/apic.h +++ linux-2.6-tip/arch/x86/include/asm/apic.h @@ -381,6 +381,26 @@ struct apic { extern struct apic *apic; /* + * APIC drivers are probed based on how they are listed in the .apicdrivers + * section. So the order is important and enforced by the ordering + * of different apic driver files in the Makefile. + * + * For the files having two apic drivers, we use apic_drivers() + * to enforce the order with in them. + */ +#define apic_driver(sym) \ + static struct apic *__apicdrivers_##sym __used \ + __aligned(sizeof(struct apic *)) \ + __section(.apicdrivers) = { &sym } + +#define apic_drivers(sym1, sym2) \ + static struct apic *__apicdrivers_##sym1##sym2[2] __used \ + __aligned(sizeof(struct apic *)) \ + __section(.apicdrivers) = { &sym1, &sym2 } + +extern struct apic *__apicdrivers[], *__apicdrivers_end[]; + +/* * APIC functionality to boot other CPUs - only used on SMP: */ #ifdef CONFIG_SMP Index: linux-2.6-tip/arch/x86/kernel/apic/Makefile =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/Makefile +++ linux-2.6-tip/arch/x86/kernel/apic/Makefile @@ -2,20 +2,25 @@ # Makefile for local APIC drivers and for the IO-APIC code # -obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o probe_$(BITS).o ipi.o +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o ipi.o obj-y += hw_nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_SMP) += ipi.o ifeq ($(CONFIG_X86_64),y) -obj-y += apic_flat_64.o -obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o -obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o +# APIC probe will depend on the listing order here obj-$(CONFIG_X86_UV) += x2apic_uv_x.o +obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o +obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o +obj-y += apic_flat_64.o endif -obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o +# APIC probe will depend on the listing order here obj-$(CONFIG_X86_NUMAQ) += numaq_32.o -obj-$(CONFIG_X86_ES7000) += es7000_32.o obj-$(CONFIG_X86_SUMMIT) += summit_32.o +obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o +obj-$(CONFIG_X86_ES7000) += es7000_32.o + +# For 32bit, probe_32 need to be listed last +obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o Index: linux-2.6-tip/arch/x86/kernel/apic/apic_flat_64.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/apic_flat_64.c +++ linux-2.6-tip/arch/x86/kernel/apic/apic_flat_64.c @@ -377,3 +377,8 @@ struct apic apic_physflat = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; + +/* + * We need to check for physflat first, so this order is important. + */ +apic_drivers(apic_physflat, apic_flat); Index: linux-2.6-tip/arch/x86/kernel/apic/x2apic_cluster.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/x2apic_cluster.c +++ linux-2.6-tip/arch/x86/kernel/apic/x2apic_cluster.c @@ -264,3 +264,5 @@ struct apic apic_x2apic_cluster = { .wait_icr_idle = native_x2apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, }; + +apic_driver(apic_x2apic_cluster); Index: linux-2.6-tip/arch/x86/kernel/apic/x2apic_phys.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/x2apic_phys.c +++ linux-2.6-tip/arch/x86/kernel/apic/x2apic_phys.c @@ -168,3 +168,5 @@ struct apic apic_x2apic_phys = { .wait_icr_idle = native_x2apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, }; + +apic_driver(apic_x2apic_phys); Index: linux-2.6-tip/arch/x86/kernel/apic/x2apic_uv_x.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/x2apic_uv_x.c +++ linux-2.6-tip/arch/x86/kernel/apic/x2apic_uv_x.c @@ -864,3 +864,5 @@ void __init uv_system_init(void) if (is_kdump_kernel()) reboot_type = BOOT_ACPI; } + +apic_driver(apic_x2apic_uv_x); Index: linux-2.6-tip/arch/x86/kernel/vmlinux.lds.S =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/vmlinux.lds.S +++ linux-2.6-tip/arch/x86/kernel/vmlinux.lds.S @@ -306,6 +306,13 @@ SECTIONS } . = ALIGN(8); + .apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) { + __apicdrivers = .; + *(.apicdrivers); + __apicdrivers_end = .; + } + + . = ALIGN(8); /* * .exit.text is discard at runtime, not link time, to deal with * references from .altinstructions and .eh_frame Index: linux-2.6-tip/arch/x86/kernel/apic/bigsmp_32.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/bigsmp_32.c +++ linux-2.6-tip/arch/x86/kernel/apic/bigsmp_32.c @@ -254,3 +254,5 @@ struct apic apic_bigsmp = { .x86_32_early_logical_apicid = bigsmp_early_logical_apicid, }; + +apic_driver(apic_bigsmp); Index: linux-2.6-tip/arch/x86/kernel/apic/es7000_32.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/es7000_32.c +++ linux-2.6-tip/arch/x86/kernel/apic/es7000_32.c @@ -747,3 +747,9 @@ struct apic __refdata apic_es7000 = { .x86_32_early_logical_apicid = es7000_early_logical_apicid, }; + +/* + * Need to check for es7000 followed by es7000_cluster, so this order + * in apic_drivers is important. + */ +apic_drivers(apic_es7000, apic_es7000_cluster); Index: linux-2.6-tip/arch/x86/kernel/apic/numaq_32.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/numaq_32.c +++ linux-2.6-tip/arch/x86/kernel/apic/numaq_32.c @@ -537,3 +537,5 @@ struct apic __refdata apic_numaq = { .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, .x86_32_numa_cpu_node = numaq_numa_cpu_node, }; + +apic_driver(apic_numaq); Index: linux-2.6-tip/arch/x86/kernel/apic/summit_32.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/summit_32.c +++ linux-2.6-tip/arch/x86/kernel/apic/summit_32.c @@ -552,3 +552,5 @@ struct apic apic_summit = { .x86_32_early_logical_apicid = summit_early_logical_apicid, }; + +apic_driver(apic_summit); Index: linux-2.6-tip/arch/x86/kernel/apic/probe_32.c =================================================================== --- linux-2.6-tip.orig/arch/x86/kernel/apic/probe_32.c +++ linux-2.6-tip/arch/x86/kernel/apic/probe_32.c @@ -174,6 +174,8 @@ struct apic apic_default = { .x86_32_early_logical_apicid = default_x86_32_early_logical_apicid, }; +apic_driver(apic_default); + extern struct apic apic_numaq; extern struct apic apic_summit; extern struct apic apic_bigsmp; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/