x86: introduce x86_quirks
authorYinghai Lu <yhlu.kernel@gmail.com>
Sat, 19 Jul 2008 09:07:25 +0000 (02:07 -0700)
committerIngo Molnar <mingo@elte.hu>
Sun, 20 Jul 2008 07:18:17 +0000 (09:18 +0200)
introduce x86_quirks array of boot-time quirk methods.

No change in functionality intended.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/e820.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/setup.c
arch/x86/kernel/visws_quirks.c
arch/x86/mach-default/setup.c
include/asm-x86/setup.h

index 6c60aeaac15f2d2f1eee78464aa962c9d0675daa..9af89078f7bb0cb2b6ce7ed958c9483b24d4402e 100644 (file)
@@ -1299,11 +1299,6 @@ void __init e820_reserve_resources(void)
        }
 }
 
-/*
- * Non-standard memory setup can be specified via this quirk:
- */
-char * (*arch_memory_setup_quirk)(void);
-
 char *__init default_machine_specific_memory_setup(void)
 {
        char *who = "BIOS-e820";
@@ -1344,8 +1339,8 @@ char *__init default_machine_specific_memory_setup(void)
 
 char *__init __attribute__((weak)) machine_specific_memory_setup(void)
 {
-       if (arch_memory_setup_quirk) {
-               char *who = arch_memory_setup_quirk();
+       if (x86_quirks->arch_memory_setup) {
+               char *who = x86_quirks->arch_memory_setup();
 
                if (who)
                        return who;
index 3b25e49380c6eed8ff660d409afb2deda8c428cd..3cbd2df3abe4916bdcfed5865ffc13c7c7ac3c12 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/bios_ebda.h>
 #include <asm/e820.h>
 #include <asm/trampoline.h>
+#include <asm/setup.h>
 
 #include <mach_apic.h>
 #ifdef CONFIG_X86_32
@@ -725,12 +726,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 
 static struct intel_mp_floating *mpf_found;
 
-/*
- * Machine specific quirk for finding the SMP config before other setup
- * activities destroy the table:
- */
-int (*mach_get_smp_config_quirk)(unsigned int early);
-
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
@@ -738,8 +733,8 @@ static void __init __get_smp_config(unsigned int early)
 {
        struct intel_mp_floating *mpf = mpf_found;
 
-       if (mach_get_smp_config_quirk) {
-               if (mach_get_smp_config_quirk(early))
+       if (x86_quirks->mach_get_smp_config) {
+               if (x86_quirks->mach_get_smp_config(early))
                        return;
        }
        if (acpi_lapic && early)
@@ -899,14 +894,12 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
        return 0;
 }
 
-int (*mach_find_smp_config_quirk)(unsigned int reserve);
-
 static void __init __find_smp_config(unsigned int reserve)
 {
        unsigned int address;
 
-       if (mach_find_smp_config_quirk) {
-               if (mach_find_smp_config_quirk(reserve))
+       if (x86_quirks->mach_find_smp_config) {
+               if (x86_quirks->mach_find_smp_config(reserve))
                        return;
        }
        /*
index 4a2b8acc1d95412eb5f7236dcb69e4733b008917..bbcc13d0b5696b2a239c07d2de6f664d79c6ad99 100644 (file)
@@ -574,6 +574,10 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
+static struct x86_quirks default_x86_quirks __initdata;
+
+struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
index e94bdb6add1d335b273eb5613962d686ffc08198..41e01b145c4800c514e07f456a126a0a0b5104e7 100644 (file)
@@ -73,7 +73,7 @@ int is_visws_box(void)
        return visws_board_type >= 0;
 }
 
-static int __init visws_time_init_quirk(void)
+static int __init visws_time_init(void)
 {
        printk(KERN_INFO "Starting Cobalt Timer system clock\n");
 
@@ -93,7 +93,7 @@ static int __init visws_time_init_quirk(void)
        return 0;
 }
 
-static int __init visws_pre_intr_init_quirk(void)
+static int __init visws_pre_intr_init(void)
 {
        init_VISWS_APIC_irqs();
 
@@ -114,7 +114,7 @@ EXPORT_SYMBOL(sgivwfb_mem_size);
 
 long long mem_size __initdata = 0;
 
-static char * __init visws_memory_setup_quirk(void)
+static char * __init visws_memory_setup(void)
 {
        long long gfx_mem_size = 8 * MB;
 
@@ -176,7 +176,7 @@ static void visws_machine_power_off(void)
        outl(PIIX_SPECIAL_STOP, 0xCFC);
 }
 
-static int __init visws_get_smp_config_quirk(unsigned int early)
+static int __init visws_get_smp_config(unsigned int early)
 {
        /*
         * Prevent MP-table parsing by the generic code:
@@ -192,7 +192,7 @@ extern unsigned int __cpuinitdata maxcpus;
  * No problem for Linux.
  */
 
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __init MP_processor_info(struct mpc_config_processor *m)
 {
        int ver, logical_apicid;
        physid_mask_t apic_cpus;
@@ -232,7 +232,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
        apic_version[m->mpc_apicid] = ver;
 }
 
-int __init visws_find_smp_config_quirk(unsigned int reserve)
+static int __init visws_find_smp_config(unsigned int reserve)
 {
        struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
        unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
@@ -258,7 +258,17 @@ int __init visws_find_smp_config_quirk(unsigned int reserve)
        return 1;
 }
 
-extern int visws_trap_init_quirk(void);
+static int visws_trap_init(void);
+
+static struct x86_quirks visws_x86_quirks __initdata = {
+       .arch_time_init         = visws_time_init,
+       .arch_pre_intr_init     = visws_pre_intr_init,
+       .arch_memory_setup      = visws_memory_setup,
+       .arch_intr_init         = NULL,
+       .arch_trap_init         = visws_trap_init,
+       .mach_get_smp_config    = visws_get_smp_config,
+       .mach_find_smp_config   = visws_find_smp_config,
+};
 
 void __init visws_early_detect(void)
 {
@@ -272,16 +282,10 @@ void __init visws_early_detect(void)
 
        /*
         * Install special quirks for timer, interrupt and memory setup:
-        */
-       arch_time_init_quirk            = visws_time_init_quirk;
-       arch_pre_intr_init_quirk        = visws_pre_intr_init_quirk;
-       arch_memory_setup_quirk         = visws_memory_setup_quirk;
-
-       /*
         * Fall back to generic behavior for traps:
+        * Override generic MP-table parsing:
         */
-       arch_intr_init_quirk            = NULL;
-       arch_trap_init_quirk            = visws_trap_init_quirk;
+       x86_quirks = &visws_x86_quirks;
 
        /*
         * Install reboot quirks:
@@ -294,12 +298,6 @@ void __init visws_early_detect(void)
         */
        no_broadcast = 0;
 
-       /*
-        * Override generic MP-table parsing:
-        */
-       mach_get_smp_config_quirk       = visws_get_smp_config_quirk;
-       mach_find_smp_config_quirk      = visws_find_smp_config_quirk;
-
 #ifdef CONFIG_X86_IO_APIC
        /*
         * Turn off IO-APIC detection and initialization:
@@ -426,7 +424,7 @@ static __init void cobalt_init(void)
                co_apic_read(CO_APIC_ID));
 }
 
-int __init visws_trap_init_quirk(void)
+static int __init visws_trap_init(void)
 {
        lithium_init();
        cobalt_init();
index 48278fa7d3dee05eeaf2ccfa9bb8c726f6dd2f84..631dbed9fb9d47493fb4ff8923c79216078226ae 100644 (file)
 #include <asm/e820.h>
 #include <asm/setup.h>
 
-/*
- * Any quirks to be performed to initialize timers/irqs/etc?
- */
-int (*arch_time_init_quirk)(void);
-int (*arch_pre_intr_init_quirk)(void);
-int (*arch_intr_init_quirk)(void);
-int (*arch_trap_init_quirk)(void);
-
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI       (1)
 #else
@@ -37,8 +29,8 @@ int no_broadcast=DEFAULT_SEND_IPI;
  **/
 void __init pre_intr_init_hook(void)
 {
-       if (arch_pre_intr_init_quirk) {
-               if (arch_pre_intr_init_quirk())
+       if (x86_quirks->arch_pre_intr_init) {
+               if (x86_quirks->arch_pre_intr_init())
                        return;
        }
        init_ISA_irqs();
@@ -64,8 +56,8 @@ static struct irqaction irq2 = {
  **/
 void __init intr_init_hook(void)
 {
-       if (arch_intr_init_quirk) {
-               if (arch_intr_init_quirk())
+       if (x86_quirks->arch_intr_init) {
+               if (x86_quirks->arch_intr_init())
                        return;
        }
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -97,8 +89,8 @@ void __init pre_setup_arch_hook(void)
  **/
 void __init trap_init_hook(void)
 {
-       if (arch_trap_init_quirk) {
-               if (arch_trap_init_quirk())
+       if (x86_quirks->arch_trap_init) {
+               if (x86_quirks->arch_trap_init())
                        return;
        }
 }
@@ -119,13 +111,13 @@ static struct irqaction irq0  = {
  **/
 void __init time_init_hook(void)
 {
-       if (arch_time_init_quirk) {
+       if (x86_quirks->arch_time_init) {
                /*
                 * A nonzero return code does not mean failure, it means
                 * that the architecture quirk does not want any
                 * generic (timer) setup to be performed after this:
                 */
-               if (arch_time_init_quirk())
+               if (x86_quirks->arch_time_init())
                        return;
        }
 
index 90ab2225e71bbefe9fb06c9d85127c555e8a8445..66191d0de3c93b8f1833c1b4e93e67e99308a45f 100644 (file)
@@ -19,13 +19,17 @@ static inline int is_visws_box(void) { return 0; }
 /*
  * Any setup quirks to be performed?
  */
-extern int (*arch_time_init_quirk)(void);
-extern int (*arch_pre_intr_init_quirk)(void);
-extern int (*arch_intr_init_quirk)(void);
-extern int (*arch_trap_init_quirk)(void);
-extern char * (*arch_memory_setup_quirk)(void);
-extern int (*mach_get_smp_config_quirk)(unsigned int early);
-extern int (*mach_find_smp_config_quirk)(unsigned int reserve);
+struct x86_quirks {
+       int (*arch_time_init)(void);
+       int (*arch_pre_intr_init)(void);
+       int (*arch_intr_init)(void);
+       int (*arch_trap_init)(void);
+       char * (*arch_memory_setup)(void);
+       int (*mach_get_smp_config)(unsigned int early);
+       int (*mach_find_smp_config)(unsigned int reserve);
+};
+
+extern struct x86_quirks *x86_quirks;
 
 #ifndef CONFIG_PARAVIRT
 #define paravirt_post_allocator_init() do {} while (0)