summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-25 16:09:31 +0100
committerThomas Gleixner <tglx@linutronix.de>2011-02-25 16:18:52 +0100
commita906fdaacca49917d83e5032dfc31f694249ad10 (patch)
tree6b00061e1db64f5f2767c129b666ee25487fd59e /arch/x86/kernel
parent4a66b1d95ad8baf6ab884a1c64461449b463eb78 (diff)
x86: dt: Cleanup local apic setup
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>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/apic/apic.c6
-rw-r--r--arch/x86/kernel/devicetree.c40
-rw-r--r--arch/x86/kernel/setup.c2
3 files changed, 24 insertions, 24 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index f0e079823c4..4f43312cfbf 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -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())
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 06e5e91939c..7a8cebc9ff2 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -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();
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 33dcbce1ab0..b3143bc74e6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -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: