]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/apic_32.c
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-2.6] / arch / x86 / kernel / apic_32.c
index cbcf72cde956f4d9494ebaab30d5a0ee6b3948ba..35a568ea8400269f4fde96377e76e1013fc5c3e3 100644 (file)
@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 /* Local APIC was disabled by the BIOS and enabled by the kernel */
 static int enabled_via_apicbase;
 
+static unsigned long apic_phys;
+
 /*
  * Get the LAPIC version
  */
@@ -377,8 +379,10 @@ void __init setup_boot_APIC_clock(void)
         */
        if (local_apic_timer_disabled) {
                /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1)
+               if (num_possible_cpus() > 1) {
+                       lapic_clockevent.mult = 1;
                        setup_APIC_timer();
+               }
                return;
        }
 
@@ -470,6 +474,19 @@ void __init setup_boot_APIC_clock(void)
 
        local_apic_timer_verify_ok = 1;
 
+       /*
+        * Do a sanity check on the APIC calibration result
+        */
+       if (calibration_result < (1000000 / HZ)) {
+               local_irq_enable();
+               printk(KERN_WARNING
+                      "APIC frequency too slow, disabling apic timer\n");
+               /* No broadcast on UP ! */
+               if (num_possible_cpus() > 1)
+                       setup_APIC_timer();
+               return;
+       }
+
        /* We trust the pm timer based calibration */
        if (!pm_referenced) {
                apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -616,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
  */
 void clear_local_APIC(void)
 {
-       int maxlvt = lapic_get_maxlvt();
+       int maxlvt;
        u32 v;
 
+       /* APIC hasn't been mapped yet */
+       if (!apic_phys)
+               return;
+
+       maxlvt = lapic_get_maxlvt();
        /*
         * Masking an LVT entry can trigger a local APIC error
         * if the vector is zero. Mask LVTERR first to prevent this.
@@ -1105,8 +1127,6 @@ no_apic:
  */
 void __init init_apic_mappings(void)
 {
-       unsigned long apic_phys;
-
        /*
         * If no local APIC can be found then set up a fake all
         * zeroes page to simulate the local APIC and another