aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic_32.c')
-rw-r--r--arch/x86/kernel/apic_32.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index a437d027f20b..2bc1186cc95a 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -177,7 +177,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
177 /* Level triggered for 82489DX */ 177 /* Level triggered for 82489DX */
178 if (!lapic_is_integrated()) 178 if (!lapic_is_integrated())
179 v |= APIC_LVT_LEVEL_TRIGGER; 179 v |= APIC_LVT_LEVEL_TRIGGER;
180 apic_write_around(APIC_LVT0, v); 180 apic_write(APIC_LVT0, v);
181} 181}
182 182
183/** 183/**
@@ -212,9 +212,6 @@ int lapic_get_maxlvt(void)
212 * this function twice on the boot CPU, once with a bogus timeout 212 * this function twice on the boot CPU, once with a bogus timeout
213 * value, second time for real. The other (noncalibrating) CPUs 213 * value, second time for real. The other (noncalibrating) CPUs
214 * call this function only once, with the real, calibrated value. 214 * call this function only once, with the real, calibrated value.
215 *
216 * We do reads before writes even if unnecessary, to get around the
217 * P5 APIC double write bug.
218 */ 215 */
219static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) 216static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
220{ 217{
@@ -229,18 +226,18 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
229 if (!irqen) 226 if (!irqen)
230 lvtt_value |= APIC_LVT_MASKED; 227 lvtt_value |= APIC_LVT_MASKED;
231 228
232 apic_write_around(APIC_LVTT, lvtt_value); 229 apic_write(APIC_LVTT, lvtt_value);
233 230
234 /* 231 /*
235 * Divide PICLK by 16 232 * Divide PICLK by 16
236 */ 233 */
237 tmp_value = apic_read(APIC_TDCR); 234 tmp_value = apic_read(APIC_TDCR);
238 apic_write_around(APIC_TDCR, (tmp_value 235 apic_write(APIC_TDCR,
239 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) 236 (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
240 | APIC_TDR_DIV_16); 237 APIC_TDR_DIV_16);
241 238
242 if (!oneshot) 239 if (!oneshot)
243 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); 240 apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
244} 241}
245 242
246/* 243/*
@@ -249,7 +246,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
249static int lapic_next_event(unsigned long delta, 246static int lapic_next_event(unsigned long delta,
250 struct clock_event_device *evt) 247 struct clock_event_device *evt)
251{ 248{
252 apic_write_around(APIC_TMICT, delta); 249 apic_write(APIC_TMICT, delta);
253 return 0; 250 return 0;
254} 251}
255 252
@@ -278,7 +275,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
278 case CLOCK_EVT_MODE_SHUTDOWN: 275 case CLOCK_EVT_MODE_SHUTDOWN:
279 v = apic_read(APIC_LVTT); 276 v = apic_read(APIC_LVTT);
280 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); 277 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
281 apic_write_around(APIC_LVTT, v); 278 apic_write(APIC_LVTT, v);
282 break; 279 break;
283 case CLOCK_EVT_MODE_RESUME: 280 case CLOCK_EVT_MODE_RESUME:
284 /* Nothing to do here */ 281 /* Nothing to do here */
@@ -693,44 +690,44 @@ void clear_local_APIC(void)
693 */ 690 */
694 if (maxlvt >= 3) { 691 if (maxlvt >= 3) {
695 v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ 692 v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
696 apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED); 693 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
697 } 694 }
698 /* 695 /*
699 * Careful: we have to set masks only first to deassert 696 * Careful: we have to set masks only first to deassert
700 * any level-triggered sources. 697 * any level-triggered sources.
701 */ 698 */
702 v = apic_read(APIC_LVTT); 699 v = apic_read(APIC_LVTT);
703 apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); 700 apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
704 v = apic_read(APIC_LVT0); 701 v = apic_read(APIC_LVT0);
705 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); 702 apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
706 v = apic_read(APIC_LVT1); 703 v = apic_read(APIC_LVT1);
707 apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED); 704 apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
708 if (maxlvt >= 4) { 705 if (maxlvt >= 4) {
709 v = apic_read(APIC_LVTPC); 706 v = apic_read(APIC_LVTPC);
710 apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); 707 apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
711 } 708 }
712 709
713 /* lets not touch this if we didn't frob it */ 710 /* lets not touch this if we didn't frob it */
714#ifdef CONFIG_X86_MCE_P4THERMAL 711#ifdef CONFIG_X86_MCE_P4THERMAL
715 if (maxlvt >= 5) { 712 if (maxlvt >= 5) {
716 v = apic_read(APIC_LVTTHMR); 713 v = apic_read(APIC_LVTTHMR);
717 apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); 714 apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
718 } 715 }
719#endif 716#endif
720 /* 717 /*
721 * Clean APIC state for other OSs: 718 * Clean APIC state for other OSs:
722 */ 719 */
723 apic_write_around(APIC_LVTT, APIC_LVT_MASKED); 720 apic_write(APIC_LVTT, APIC_LVT_MASKED);
724 apic_write_around(APIC_LVT0, APIC_LVT_MASKED); 721 apic_write(APIC_LVT0, APIC_LVT_MASKED);
725 apic_write_around(APIC_LVT1, APIC_LVT_MASKED); 722 apic_write(APIC_LVT1, APIC_LVT_MASKED);
726 if (maxlvt >= 3) 723 if (maxlvt >= 3)
727 apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); 724 apic_write(APIC_LVTERR, APIC_LVT_MASKED);
728 if (maxlvt >= 4) 725 if (maxlvt >= 4)
729 apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); 726 apic_write(APIC_LVTPC, APIC_LVT_MASKED);
730 727
731#ifdef CONFIG_X86_MCE_P4THERMAL 728#ifdef CONFIG_X86_MCE_P4THERMAL
732 if (maxlvt >= 5) 729 if (maxlvt >= 5)
733 apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); 730 apic_write(APIC_LVTTHMR, APIC_LVT_MASKED);
734#endif 731#endif
735 /* Integrated APIC (!82489DX) ? */ 732 /* Integrated APIC (!82489DX) ? */
736 if (lapic_is_integrated()) { 733 if (lapic_is_integrated()) {
@@ -756,7 +753,7 @@ void disable_local_APIC(void)
756 */ 753 */
757 value = apic_read(APIC_SPIV); 754 value = apic_read(APIC_SPIV);
758 value &= ~APIC_SPIV_APIC_ENABLED; 755 value &= ~APIC_SPIV_APIC_ENABLED;
759 apic_write_around(APIC_SPIV, value); 756 apic_write(APIC_SPIV, value);
760 757
761 /* 758 /*
762 * When LAPIC was disabled by the BIOS and enabled by the kernel, 759 * When LAPIC was disabled by the BIOS and enabled by the kernel,
@@ -865,8 +862,8 @@ void __init sync_Arb_IDs(void)
865 apic_wait_icr_idle(); 862 apic_wait_icr_idle();
866 863
867 apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); 864 apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
868 apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG 865 apic_write(APIC_ICR,
869 | APIC_DM_INIT); 866 APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT);
870} 867}
871 868
872/* 869/*
@@ -902,16 +899,16 @@ void __init init_bsp_APIC(void)
902 else 899 else
903 value |= APIC_SPIV_FOCUS_DISABLED; 900 value |= APIC_SPIV_FOCUS_DISABLED;
904 value |= SPURIOUS_APIC_VECTOR; 901 value |= SPURIOUS_APIC_VECTOR;
905 apic_write_around(APIC_SPIV, value); 902 apic_write(APIC_SPIV, value);
906 903
907 /* 904 /*
908 * Set up the virtual wire mode. 905 * Set up the virtual wire mode.
909 */ 906 */
910 apic_write_around(APIC_LVT0, APIC_DM_EXTINT); 907 apic_write(APIC_LVT0, APIC_DM_EXTINT);
911 value = APIC_DM_NMI; 908 value = APIC_DM_NMI;
912 if (!lapic_is_integrated()) /* 82489DX */ 909 if (!lapic_is_integrated()) /* 82489DX */
913 value |= APIC_LVT_LEVEL_TRIGGER; 910 value |= APIC_LVT_LEVEL_TRIGGER;
914 apic_write_around(APIC_LVT1, value); 911 apic_write(APIC_LVT1, value);
915} 912}
916 913
917static void __cpuinit lapic_setup_esr(void) 914static void __cpuinit lapic_setup_esr(void)
@@ -926,7 +923,7 @@ static void __cpuinit lapic_setup_esr(void)
926 923
927 /* enables sending errors */ 924 /* enables sending errors */
928 value = ERROR_APIC_VECTOR; 925 value = ERROR_APIC_VECTOR;
929 apic_write_around(APIC_LVTERR, value); 926 apic_write(APIC_LVTERR, value);
930 /* 927 /*
931 * spec says clear errors after enabling vector. 928 * spec says clear errors after enabling vector.
932 */ 929 */
@@ -989,7 +986,7 @@ void __cpuinit setup_local_APIC(void)
989 */ 986 */
990 value = apic_read(APIC_TASKPRI); 987 value = apic_read(APIC_TASKPRI);
991 value &= ~APIC_TPRI_MASK; 988 value &= ~APIC_TPRI_MASK;
992 apic_write_around(APIC_TASKPRI, value); 989 apic_write(APIC_TASKPRI, value);
993 990
994 /* 991 /*
995 * After a crash, we no longer service the interrupts and a pending 992 * After a crash, we no longer service the interrupts and a pending
@@ -1047,7 +1044,7 @@ void __cpuinit setup_local_APIC(void)
1047 * Set spurious IRQ vector 1044 * Set spurious IRQ vector
1048 */ 1045 */
1049 value |= SPURIOUS_APIC_VECTOR; 1046 value |= SPURIOUS_APIC_VECTOR;
1050 apic_write_around(APIC_SPIV, value); 1047 apic_write(APIC_SPIV, value);
1051 1048
1052 /* 1049 /*
1053 * Set up LVT0, LVT1: 1050 * Set up LVT0, LVT1:
@@ -1069,7 +1066,7 @@ void __cpuinit setup_local_APIC(void)
1069 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", 1066 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
1070 smp_processor_id()); 1067 smp_processor_id());
1071 } 1068 }
1072 apic_write_around(APIC_LVT0, value); 1069 apic_write(APIC_LVT0, value);
1073 1070
1074 /* 1071 /*
1075 * only the BP should see the LINT1 NMI signal, obviously. 1072 * only the BP should see the LINT1 NMI signal, obviously.
@@ -1080,7 +1077,7 @@ void __cpuinit setup_local_APIC(void)
1080 value = APIC_DM_NMI | APIC_LVT_MASKED; 1077 value = APIC_DM_NMI | APIC_LVT_MASKED;
1081 if (!integrated) /* 82489DX */ 1078 if (!integrated) /* 82489DX */
1082 value |= APIC_LVT_LEVEL_TRIGGER; 1079 value |= APIC_LVT_LEVEL_TRIGGER;
1083 apic_write_around(APIC_LVT1, value); 1080 apic_write(APIC_LVT1, value);
1084} 1081}
1085 1082
1086void __cpuinit end_local_APIC_setup(void) 1083void __cpuinit end_local_APIC_setup(void)
@@ -1091,7 +1088,7 @@ void __cpuinit end_local_APIC_setup(void)
1091 /* Disable the local apic timer */ 1088 /* Disable the local apic timer */
1092 value = apic_read(APIC_LVTT); 1089 value = apic_read(APIC_LVTT);
1093 value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); 1090 value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
1094 apic_write_around(APIC_LVTT, value); 1091 apic_write(APIC_LVTT, value);
1095 1092
1096 setup_apic_nmi_watchdog(NULL); 1093 setup_apic_nmi_watchdog(NULL);
1097 apic_pm_activate(); 1094 apic_pm_activate();
@@ -1419,7 +1416,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1419 value &= ~APIC_VECTOR_MASK; 1416 value &= ~APIC_VECTOR_MASK;
1420 value |= APIC_SPIV_APIC_ENABLED; 1417 value |= APIC_SPIV_APIC_ENABLED;
1421 value |= 0xf; 1418 value |= 0xf;
1422 apic_write_around(APIC_SPIV, value); 1419 apic_write(APIC_SPIV, value);
1423 1420
1424 if (!virt_wire_setup) { 1421 if (!virt_wire_setup) {
1425 /* 1422 /*
@@ -1432,10 +1429,10 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1432 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); 1429 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1433 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 1430 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1434 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); 1431 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
1435 apic_write_around(APIC_LVT0, value); 1432 apic_write(APIC_LVT0, value);
1436 } else { 1433 } else {
1437 /* Disable LVT0 */ 1434 /* Disable LVT0 */
1438 apic_write_around(APIC_LVT0, APIC_LVT_MASKED); 1435 apic_write(APIC_LVT0, APIC_LVT_MASKED);
1439 } 1436 }
1440 1437
1441 /* 1438 /*
@@ -1449,7 +1446,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1449 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); 1446 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1450 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 1447 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1451 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); 1448 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
1452 apic_write_around(APIC_LVT1, value); 1449 apic_write(APIC_LVT1, value);
1453 } 1450 }
1454} 1451}
1455 1452