Lines 26-31
Link Here
|
26 |
#include <linux/kernel_stat.h> |
26 |
#include <linux/kernel_stat.h> |
27 |
#include <linux/sysdev.h> |
27 |
#include <linux/sysdev.h> |
28 |
#include <linux/cpu.h> |
28 |
#include <linux/cpu.h> |
|
|
29 |
#include <linux/module.h> |
29 |
|
30 |
|
30 |
#include <asm/atomic.h> |
31 |
#include <asm/atomic.h> |
31 |
#include <asm/smp.h> |
32 |
#include <asm/smp.h> |
Lines 37-46
Link Here
|
37 |
#include <asm/i8253.h> |
38 |
#include <asm/i8253.h> |
38 |
|
39 |
|
39 |
#include <mach_apic.h> |
40 |
#include <mach_apic.h> |
|
|
41 |
#include <mach_ipi.h> |
40 |
|
42 |
|
41 |
#include "io_ports.h" |
43 |
#include "io_ports.h" |
42 |
|
44 |
|
43 |
/* |
45 |
/* |
|
|
46 |
* cpu_mask that denotes the CPUs that needs timer interrupt coming in as |
47 |
* IPIs in place of local APIC timers |
48 |
*/ |
49 |
static cpumask_t timer_interrupt_broadcast_ipi_mask; |
50 |
|
51 |
/* |
44 |
* Knob to control our willingness to enable the local APIC. |
52 |
* Knob to control our willingness to enable the local APIC. |
45 |
*/ |
53 |
*/ |
46 |
int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ |
54 |
int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ |
Lines 931-941
void (*wait_timer_tick)(void) __devinitd
Link Here
|
931 |
static void __setup_APIC_LVTT(unsigned int clocks) |
939 |
static void __setup_APIC_LVTT(unsigned int clocks) |
932 |
{ |
940 |
{ |
933 |
unsigned int lvtt_value, tmp_value, ver; |
941 |
unsigned int lvtt_value, tmp_value, ver; |
|
|
942 |
int cpu = smp_processor_id(); |
934 |
|
943 |
|
935 |
ver = GET_APIC_VERSION(apic_read(APIC_LVR)); |
944 |
ver = GET_APIC_VERSION(apic_read(APIC_LVR)); |
936 |
lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; |
945 |
lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; |
937 |
if (!APIC_INTEGRATED(ver)) |
946 |
if (!APIC_INTEGRATED(ver)) |
938 |
lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); |
947 |
lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); |
|
|
948 |
|
949 |
if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) |
950 |
lvtt_value |= APIC_LVT_MASKED; |
951 |
|
939 |
apic_write_around(APIC_LVTT, lvtt_value); |
952 |
apic_write_around(APIC_LVTT, lvtt_value); |
940 |
|
953 |
|
941 |
/* |
954 |
/* |
Lines 1068-1074
void __devinit setup_secondary_APIC_cloc
Link Here
|
1068 |
setup_APIC_timer(calibration_result); |
1081 |
setup_APIC_timer(calibration_result); |
1069 |
} |
1082 |
} |
1070 |
|
1083 |
|
1071 |
void __devinit disable_APIC_timer(void) |
1084 |
void disable_APIC_timer(void) |
1072 |
{ |
1085 |
{ |
1073 |
if (using_apic_timer) { |
1086 |
if (using_apic_timer) { |
1074 |
unsigned long v; |
1087 |
unsigned long v; |
Lines 1080-1086
void __devinit disable_APIC_timer(void)
Link Here
|
1080 |
|
1093 |
|
1081 |
void enable_APIC_timer(void) |
1094 |
void enable_APIC_timer(void) |
1082 |
{ |
1095 |
{ |
1083 |
if (using_apic_timer) { |
1096 |
int cpu = smp_processor_id(); |
|
|
1097 |
|
1098 |
if (using_apic_timer && |
1099 |
!cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { |
1084 |
unsigned long v; |
1100 |
unsigned long v; |
1085 |
|
1101 |
|
1086 |
v = apic_read(APIC_LVTT); |
1102 |
v = apic_read(APIC_LVTT); |
Lines 1088-1093
void enable_APIC_timer(void)
Link Here
|
1088 |
} |
1104 |
} |
1089 |
} |
1105 |
} |
1090 |
|
1106 |
|
|
|
1107 |
void switch_APIC_timer_to_ipi(void *cpumask) |
1108 |
{ |
1109 |
cpumask_t mask = *(cpumask_t *)cpumask; |
1110 |
int cpu = smp_processor_id(); |
1111 |
|
1112 |
if (cpu_isset(cpu, mask) && |
1113 |
!cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { |
1114 |
disable_APIC_timer(); |
1115 |
cpu_set(cpu, timer_interrupt_broadcast_ipi_mask); |
1116 |
} |
1117 |
} |
1118 |
EXPORT_SYMBOL(switch_APIC_timer_to_ipi); |
1119 |
|
1120 |
void switch_ipi_to_APIC_timer(void *cpumask) |
1121 |
{ |
1122 |
cpumask_t mask = *(cpumask_t *)cpumask; |
1123 |
int cpu = smp_processor_id(); |
1124 |
|
1125 |
if (cpu_isset(cpu, mask) && |
1126 |
cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { |
1127 |
cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask); |
1128 |
enable_APIC_timer(); |
1129 |
} |
1130 |
} |
1131 |
EXPORT_SYMBOL(switch_ipi_to_APIC_timer); |
1132 |
|
1091 |
#undef APIC_DIVISOR |
1133 |
#undef APIC_DIVISOR |
1092 |
|
1134 |
|
1093 |
/* |
1135 |
/* |
Lines 1152-1157
fastcall void smp_apic_timer_interrupt(s
Link Here
|
1152 |
irq_exit(); |
1194 |
irq_exit(); |
1153 |
} |
1195 |
} |
1154 |
|
1196 |
|
|
|
1197 |
#ifndef CONFIG_SMP |
1198 |
static void up_apic_timer_interrupt_call(struct pt_regs *regs) |
1199 |
{ |
1200 |
int cpu = smp_processor_id(); |
1201 |
|
1202 |
/* |
1203 |
* the NMI deadlock-detector uses this. |
1204 |
*/ |
1205 |
per_cpu(irq_stat, cpu).apic_timer_irqs++; |
1206 |
|
1207 |
smp_local_timer_interrupt(regs); |
1208 |
} |
1209 |
#endif |
1210 |
|
1211 |
void smp_send_timer_broadcast_ipi(struct pt_regs *regs) |
1212 |
{ |
1213 |
cpumask_t mask; |
1214 |
|
1215 |
cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask); |
1216 |
if (!cpus_empty(mask)) { |
1217 |
#ifdef CONFIG_SMP |
1218 |
send_IPI_mask(mask, LOCAL_TIMER_VECTOR); |
1219 |
#else |
1220 |
/* |
1221 |
* We can directly call the apic timer interrupt handler |
1222 |
* in UP case. Minus all irq related functions |
1223 |
*/ |
1224 |
up_apic_timer_interrupt_call(regs); |
1225 |
#endif |
1226 |
} |
1227 |
} |
1228 |
|
1155 |
int setup_profiling_timer(unsigned int multiplier) |
1229 |
int setup_profiling_timer(unsigned int multiplier) |
1156 |
{ |
1230 |
{ |
1157 |
return -EINVAL; |
1231 |
return -EINVAL; |