aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-25 10:09:31 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-25 10:18:52 -0500
commita906fdaacca49917d83e5032dfc31f694249ad10 (patch)
tree6b00061e1db64f5f2767c129b666ee25487fd59e
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>
-rw-r--r--arch/x86/include/asm/apic.h2
-rw-r--r--arch/x86/include/asm/prom.h6
-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
-rw-r--r--arch/x86/platform/ce4100/ce4100.c4
6 files changed, 29 insertions, 31 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 3c896946f4c..4afe512120a 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -240,7 +240,7 @@ extern void setup_boot_APIC_clock(void);
240extern void setup_secondary_APIC_clock(void); 240extern void setup_secondary_APIC_clock(void);
241extern int APIC_init_uniprocessor(void); 241extern int APIC_init_uniprocessor(void);
242extern void enable_NMI_through_LVT0(void); 242extern void enable_NMI_through_LVT0(void);
243extern int apic_force_enable(void); 243extern int apic_force_enable(unsigned long addr);
244 244
245/* 245/*
246 * On 32bit this is mach-xxx local 246 * On 32bit this is mach-xxx local
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index f58361ba735..971e0b46446 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -28,9 +28,8 @@ extern int of_ioapic;
28extern u64 initial_dtb; 28extern u64 initial_dtb;
29extern void add_dtb(u64 data); 29extern void add_dtb(u64 data);
30extern void x86_add_irq_domains(void); 30extern void x86_add_irq_domains(void);
31void x86_dtb_find_config(void);
32void x86_dtb_get_config(unsigned int unused);
33void __cpuinit x86_of_pci_init(void); 31void __cpuinit x86_of_pci_init(void);
32void x86_dtb_init(void);
34 33
35static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) 34static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
36{ 35{
@@ -46,8 +45,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
46static inline void add_dtb(u64 data) { } 45static inline void add_dtb(u64 data) { }
47static inline void x86_add_irq_domains(void) { } 46static inline void x86_add_irq_domains(void) { }
48static inline void x86_of_pci_init(void) { } 47static inline void x86_of_pci_init(void) { }
49#define x86_dtb_find_config x86_init_noop 48static inline void x86_dtb_init(void) { }
50#define x86_dtb_get_config x86_init_uint_noop
51#define of_ioapic 0 49#define of_ioapic 0
52#endif 50#endif
53 51
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)
1563 return 0; 1563 return 0;
1564} 1564}
1565 1565
1566int apic_force_enable(void) 1566int apic_force_enable(unsigned long addr)
1567{ 1567{
1568 u32 h, l; 1568 u32 h, l;
1569 1569
@@ -1579,7 +1579,7 @@ int apic_force_enable(void)
1579 if (!(l & MSR_IA32_APICBASE_ENABLE)) { 1579 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
1580 pr_info("Local APIC disabled by BIOS -- reenabling.\n"); 1580 pr_info("Local APIC disabled by BIOS -- reenabling.\n");
1581 l &= ~MSR_IA32_APICBASE_BASE; 1581 l &= ~MSR_IA32_APICBASE_BASE;
1582 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; 1582 l |= MSR_IA32_APICBASE_ENABLE | addr;
1583 wrmsr(MSR_IA32_APICBASE, l, h); 1583 wrmsr(MSR_IA32_APICBASE, l, h);
1584 enabled_via_apicbase = 1; 1584 enabled_via_apicbase = 1;
1585 } 1585 }
@@ -1620,7 +1620,7 @@ static int __init detect_init_APIC(void)
1620 "you can enable it with \"lapic\"\n"); 1620 "you can enable it with \"lapic\"\n");
1621 return -1; 1621 return -1;
1622 } 1622 }
1623 if (apic_force_enable()) 1623 if (apic_force_enable(APIC_DEFAULT_PHYS_BASE))
1624 return -1; 1624 return -1;
1625 } else { 1625 } else {
1626 if (apic_verify()) 1626 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);
26 26
27int __initdata of_ioapic; 27int __initdata of_ioapic;
28 28
29#ifdef CONFIG_X86_IO_APIC
29static void add_interrupt_host(struct irq_domain *ih) 30static void add_interrupt_host(struct irq_domain *ih)
30{ 31{
31 unsigned long flags; 32 unsigned long flags;
@@ -34,6 +35,7 @@ static void add_interrupt_host(struct irq_domain *ih)
34 list_add(&ih->l, &irq_domains); 35 list_add(&ih->l, &irq_domains);
35 raw_spin_unlock_irqrestore(&big_irq_lock, flags); 36 raw_spin_unlock_irqrestore(&big_irq_lock, flags);
36} 37}
38#endif
37 39
38static struct irq_domain *get_ih_from_node(struct device_node *controller) 40static struct irq_domain *get_ih_from_node(struct device_node *controller)
39{ 41{
@@ -223,18 +225,28 @@ static void __init dtb_setup_hpet(void)
223static void __init dtb_lapic_setup(void) 225static void __init dtb_lapic_setup(void)
224{ 226{
225#ifdef CONFIG_X86_LOCAL_APIC 227#ifdef CONFIG_X86_LOCAL_APIC
226 if (apic_force_enable()) 228 struct device_node *dn;
229 struct resource r;
230 int ret;
231
232 dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic");
233 if (!dn)
234 return;
235
236 ret = of_address_to_resource(dn, 0, &r);
237 if (WARN_ON(ret))
227 return; 238 return;
228 239
240 /* Did the boot loader setup the local APIC ? */
241 if (!cpu_has_apic) {
242 if (apic_force_enable(r.start))
243 return;
244 }
229 smp_found_config = 1; 245 smp_found_config = 1;
230 pic_mode = 1; 246 pic_mode = 1;
231 /* Required for ioapic registration */ 247 register_lapic_address(r.start);
232 set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
233 if (boot_cpu_physical_apicid == -1U)
234 boot_cpu_physical_apicid = read_apic_id();
235
236 generic_processor_info(boot_cpu_physical_apicid, 248 generic_processor_info(boot_cpu_physical_apicid,
237 GET_APIC_VERSION(apic_read(APIC_LVR))); 249 GET_APIC_VERSION(apic_read(APIC_LVR)));
238#endif 250#endif
239} 251}
240 252
@@ -259,9 +271,6 @@ static void __init dtb_ioapic_setup(void)
259{ 271{
260 struct device_node *dn; 272 struct device_node *dn;
261 273
262 if (!smp_found_config)
263 return;
264
265 for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic") 274 for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
266 dtb_add_ioapic(dn); 275 dtb_add_ioapic(dn);
267 276
@@ -270,7 +279,6 @@ static void __init dtb_ioapic_setup(void)
270 return; 279 return;
271 } 280 }
272 printk(KERN_ERR "Error: No information about IO-APIC in OF.\n"); 281 printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
273 smp_found_config = 0;
274} 282}
275#else 283#else
276static void __init dtb_ioapic_setup(void) {} 284static void __init dtb_ioapic_setup(void) {}
@@ -282,14 +290,6 @@ static void __init dtb_apic_setup(void)
282 dtb_ioapic_setup(); 290 dtb_ioapic_setup();
283} 291}
284 292
285void __init x86_dtb_find_config(void)
286{
287 if (initial_dtb)
288 smp_found_config = 1;
289 else
290 printk(KERN_ERR "Missing device tree!.\n");
291}
292
293#ifdef CONFIG_OF_FLATTREE 293#ifdef CONFIG_OF_FLATTREE
294static void __init x86_flattree_get_config(void) 294static void __init x86_flattree_get_config(void)
295{ 295{
@@ -325,7 +325,7 @@ static void __init x86_flattree_get_config(void)
325static inline void x86_flattree_get_config(void) { } 325static inline void x86_flattree_get_config(void) { }
326#endif 326#endif
327 327
328void __init x86_dtb_get_config(unsigned int unused) 328void __init x86_dtb_init(void)
329{ 329{
330 x86_flattree_get_config(); 330 x86_flattree_get_config();
331 331
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)
1044 * Read APIC and some other early information from ACPI tables. 1044 * Read APIC and some other early information from ACPI tables.
1045 */ 1045 */
1046 acpi_boot_init(); 1046 acpi_boot_init();
1047
1048 sfi_init(); 1047 sfi_init();
1048 x86_dtb_init();
1049 1049
1050 /* 1050 /*
1051 * get boot-time SMP configuration: 1051 * get boot-time SMP configuration:
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index b3436d344b4..68c0dbcc95b 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -134,8 +134,8 @@ void __init x86_ce4100_early_setup(void)
134 x86_init.oem.arch_setup = sdv_arch_setup; 134 x86_init.oem.arch_setup = sdv_arch_setup;
135 x86_platform.i8042_detect = ce4100_i8042_detect; 135 x86_platform.i8042_detect = ce4100_i8042_detect;
136 x86_init.resources.probe_roms = x86_init_noop; 136 x86_init.resources.probe_roms = x86_init_noop;
137 x86_init.mpparse.get_smp_config = x86_dtb_get_config; 137 x86_init.mpparse.get_smp_config = x86_init_uint_noop;
138 x86_init.mpparse.find_smp_config = x86_dtb_find_config; 138 x86_init.mpparse.find_smp_config = x86_init_noop;
139 139
140#ifdef CONFIG_X86_IO_APIC 140#ifdef CONFIG_X86_IO_APIC
141 x86_init.pci.init_irq = sdv_pci_init; 141 x86_init.pci.init_irq = sdv_pci_init;