x86: dt: Cleanup local apic setup
authorThomas Gleixner <tglx@linutronix.de>
Fri, 25 Feb 2011 15:09:31 +0000 (16:09 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 25 Feb 2011 15:18:52 +0000 (16:18 +0100)
Up to now we force enable the local apic in the devicetree setup
uncoditionally and set smp_found_config unconditionally to 1 when a
devicetree blob is available. This breaks, when local apic is disabled
in the Kconfig.

Make it consistent by initializing device tree explicitely before
smp_get_config() so a non lapic configuration could be used as well.
To be functional that would require to implement PIT as an interrupt
host, but the only user of this code until now is ce4100 which
requires apics to be available. So we leave this up to those who need
it.

Tested-by: Sebastian Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/include/asm/apic.h
arch/x86/include/asm/prom.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/devicetree.c
arch/x86/kernel/setup.c
arch/x86/platform/ce4100/ce4100.c

index 3c896946f4cccfcc06f6be0a0bf5dd9739efdc82..4afe512120a9ccfa6cd1d9e52414066f5569b598 100644 (file)
@@ -240,7 +240,7 @@ extern void setup_boot_APIC_clock(void);
 extern void setup_secondary_APIC_clock(void);
 extern int APIC_init_uniprocessor(void);
 extern void enable_NMI_through_LVT0(void);
-extern int apic_force_enable(void);
+extern int apic_force_enable(unsigned long addr);
 
 /*
  * On 32bit this is mach-xxx local
index f58361ba7357d2ca6c78c1236ed6586fdd6f8031..971e0b46446e091761ffe759d4f056d484fe980c 100644 (file)
@@ -28,9 +28,8 @@ extern int of_ioapic;
 extern u64 initial_dtb;
 extern void add_dtb(u64 data);
 extern void x86_add_irq_domains(void);
-void x86_dtb_find_config(void);
-void x86_dtb_get_config(unsigned int unused);
 void __cpuinit x86_of_pci_init(void);
+void x86_dtb_init(void);
 
 static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
 {
@@ -46,8 +45,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
 static inline void add_dtb(u64 data) { }
 static inline void x86_add_irq_domains(void) { }
 static inline void x86_of_pci_init(void) { }
-#define x86_dtb_find_config x86_init_noop
-#define x86_dtb_get_config x86_init_uint_noop
+static inline void x86_dtb_init(void) { }
 #define of_ioapic 0
 #endif
 
index f0e079823c432153027c2b855a87412e8fe7ee89..4f43312cfbf8c3cdbf2913ceba01604a87e30980 100644 (file)
@@ -1563,7 +1563,7 @@ static int apic_verify(void)
        return 0;
 }
 
-int apic_force_enable(void)
+int apic_force_enable(unsigned long addr)
 {
        u32 h, l;
 
@@ -1579,7 +1579,7 @@ int apic_force_enable(void)
        if (!(l & MSR_IA32_APICBASE_ENABLE)) {
                pr_info("Local APIC disabled by BIOS -- reenabling.\n");
                l &= ~MSR_IA32_APICBASE_BASE;
-               l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+               l |= MSR_IA32_APICBASE_ENABLE | addr;
                wrmsr(MSR_IA32_APICBASE, l, h);
                enabled_via_apicbase = 1;
        }
@@ -1620,7 +1620,7 @@ static int __init detect_init_APIC(void)
                                "you can enable it with \"lapic\"\n");
                        return -1;
                }
-               if (apic_force_enable())
+               if (apic_force_enable(APIC_DEFAULT_PHYS_BASE))
                        return -1;
        } else {
                if (apic_verify())
index 06e5e91939c58e8092144f8ab1c9d5c15312cea9..7a8cebc9ff298ce0a788cc269e83efcd57a607d2 100644 (file)
@@ -26,6 +26,7 @@ static DEFINE_RAW_SPINLOCK(big_irq_lock);
 
 int __initdata of_ioapic;
 
+#ifdef CONFIG_X86_IO_APIC
 static void add_interrupt_host(struct irq_domain *ih)
 {
        unsigned long flags;
@@ -34,6 +35,7 @@ static void add_interrupt_host(struct irq_domain *ih)
        list_add(&ih->l, &irq_domains);
        raw_spin_unlock_irqrestore(&big_irq_lock, flags);
 }
+#endif
 
 static struct irq_domain *get_ih_from_node(struct device_node *controller)
 {
@@ -223,18 +225,28 @@ static void __init dtb_setup_hpet(void)
 static void __init dtb_lapic_setup(void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-       if (apic_force_enable())
+       struct device_node *dn;
+       struct resource r;
+       int ret;
+
+       dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic");
+       if (!dn)
+               return;
+
+       ret = of_address_to_resource(dn, 0, &r);
+       if (WARN_ON(ret))
                return;
 
+       /* Did the boot loader setup the local APIC ? */
+       if (!cpu_has_apic) {
+               if (apic_force_enable(r.start))
+                       return;
+       }
        smp_found_config = 1;
        pic_mode = 1;
-       /* Required for ioapic registration */
-       set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
-       if (boot_cpu_physical_apicid == -1U)
-               boot_cpu_physical_apicid = read_apic_id();
-
+       register_lapic_address(r.start);
        generic_processor_info(boot_cpu_physical_apicid,
-                       GET_APIC_VERSION(apic_read(APIC_LVR)));
+                              GET_APIC_VERSION(apic_read(APIC_LVR)));
 #endif
 }
 
@@ -259,9 +271,6 @@ static void __init dtb_ioapic_setup(void)
 {
        struct device_node *dn;
 
-       if (!smp_found_config)
-               return;
-
        for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
                dtb_add_ioapic(dn);
 
@@ -270,7 +279,6 @@ static void __init dtb_ioapic_setup(void)
                return;
        }
        printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
-       smp_found_config = 0;
 }
 #else
 static void __init dtb_ioapic_setup(void) {}
@@ -282,14 +290,6 @@ static void __init dtb_apic_setup(void)
        dtb_ioapic_setup();
 }
 
-void __init x86_dtb_find_config(void)
-{
-       if (initial_dtb)
-               smp_found_config = 1;
-       else
-               printk(KERN_ERR "Missing device tree!.\n");
-}
-
 #ifdef CONFIG_OF_FLATTREE
 static void __init x86_flattree_get_config(void)
 {
@@ -325,7 +325,7 @@ static void __init x86_flattree_get_config(void)
 static inline void x86_flattree_get_config(void) { }
 #endif
 
-void __init x86_dtb_get_config(unsigned int unused)
+void __init x86_dtb_init(void)
 {
        x86_flattree_get_config();
 
index 33dcbce1ab0fab86cdb872d1b33ff7e98ea55077..b3143bc74e6c4fe6564af79ff12a584694cec295 100644 (file)
@@ -1044,8 +1044,8 @@ void __init setup_arch(char **cmdline_p)
         * Read APIC and some other early information from ACPI tables.
         */
        acpi_boot_init();
-
        sfi_init();
+       x86_dtb_init();
 
        /*
         * get boot-time SMP configuration:
index b3436d344b411acf30e1e0c7aba846c2707bf5fa..68c0dbcc95beda7976fca133324a91ebbc88a023 100644 (file)
@@ -134,8 +134,8 @@ void __init x86_ce4100_early_setup(void)
        x86_init.oem.arch_setup = sdv_arch_setup;
        x86_platform.i8042_detect = ce4100_i8042_detect;
        x86_init.resources.probe_roms = x86_init_noop;
-       x86_init.mpparse.get_smp_config = x86_dtb_get_config;
-       x86_init.mpparse.find_smp_config = x86_dtb_find_config;
+       x86_init.mpparse.get_smp_config = x86_init_uint_noop;
+       x86_init.mpparse.find_smp_config = x86_init_noop;
 
 #ifdef CONFIG_X86_IO_APIC
        x86_init.pci.init_irq = sdv_pci_init;
This page took 0.030739 seconds and 5 git commands to generate.