Merge tag 'x86_misc_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / arch / x86 / kernel / apic / apic.c
index ed7d9cf71f68deb122f2c086718b5f45cfe5ce6a..189d3a5e471adc43c44b7d6aa8d2805a0a9a475b 100644 (file)
@@ -320,6 +320,9 @@ int lapic_get_maxlvt(void)
 #define APIC_DIVISOR 16
 #define TSC_DIVISOR  8
 
+/* i82489DX specific */
+#define                I82489DX_BASE_DIVIDER           (((0x2) << 18))
+
 /*
  * This function sets up the local APIC timer, with a timeout of
  * 'clocks' APIC bus clock. During calibration we actually call
@@ -340,8 +343,14 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
        else if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
                lvtt_value |= APIC_LVT_TIMER_TSCDEADLINE;
 
+       /*
+        * The i82489DX APIC uses bit 18 and 19 for the base divider.  This
+        * overlaps with bit 18 on integrated APICs, but is not documented
+        * in the SDM. No problem though. i82489DX equipped systems do not
+        * have TSC deadline timer.
+        */
        if (!lapic_is_integrated())
-               lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
+               lvtt_value |= I82489DX_BASE_DIVIDER;
 
        if (!irqen)
                lvtt_value |= APIC_LVT_MASKED;
@@ -1419,22 +1428,21 @@ void __init apic_intr_mode_init(void)
                return;
        case APIC_VIRTUAL_WIRE:
                pr_info("APIC: Switch to virtual wire mode setup\n");
-               default_setup_apic_routing();
                break;
        case APIC_VIRTUAL_WIRE_NO_CONFIG:
                pr_info("APIC: Switch to virtual wire mode setup with no configuration\n");
                upmode = true;
-               default_setup_apic_routing();
                break;
        case APIC_SYMMETRIC_IO:
                pr_info("APIC: Switch to symmetric I/O mode setup\n");
-               default_setup_apic_routing();
                break;
        case APIC_SYMMETRIC_IO_NO_ROUTING:
                pr_info("APIC: Switch to symmetric I/O mode setup in no SMP routine\n");
                break;
        }
 
+       default_setup_apic_routing();
+
        if (x86_platform.apic_post_init)
                x86_platform.apic_post_init();
 
@@ -2551,6 +2559,16 @@ u32 x86_msi_msg_get_destid(struct msi_msg *msg, bool extid)
 }
 EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid);
 
+#ifdef CONFIG_X86_64
+void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler)
+{
+       struct apic **drv;
+
+       for (drv = __apicdrivers; drv < __apicdrivers_end; drv++)
+               (*drv)->wakeup_secondary_cpu_64 = handler;
+}
+#endif
+
 /*
  * Override the generic EOI implementation with an optimized version.
  * Only called during early boot when only one CPU is active and with