View | Details | Raw Unified | Return to bug 2560 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.6.15-rc3/arch/i386/kernel/time.c (+6 lines)
Lines 302-307 irqreturn_t timer_interrupt(int irq, voi Link Here
302
	do_timer_interrupt(irq, regs);
302
	do_timer_interrupt(irq, regs);
303
303
304
	write_sequnlock(&xtime_lock);
304
	write_sequnlock(&xtime_lock);
305
306
#ifdef CONFIG_X86_LOCAL_APIC
307
	if (using_apic_timer)
308
		smp_send_timer_broadcast_ipi(regs);
309
#endif
310
305
	return IRQ_HANDLED;
311
	return IRQ_HANDLED;
306
}
312
}
307
313
(-)linux-2.6.15-rc3/include/asm-i386/apic.h (+5 lines)
Lines 132-137 extern unsigned int nmi_watchdog; Link Here
132
132
133
extern int disable_timer_pin_1;
133
extern int disable_timer_pin_1;
134
134
135
void smp_send_timer_broadcast_ipi(struct pt_regs *regs);
136
void switch_APIC_timer_to_ipi(void *cpumask);
137
void switch_ipi_to_APIC_timer(void *cpumask);
138
#define ARCH_APICTIMER_STOPS_ON_C3	1
139
135
#else /* !CONFIG_X86_LOCAL_APIC */
140
#else /* !CONFIG_X86_LOCAL_APIC */
136
static inline void lapic_shutdown(void) { }
141
static inline void lapic_shutdown(void) { }
137
142
(-)linux-2.6.15-rc3/arch/i386/kernel/apic.c (-2 / +76 lines)
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;
(-)linux-2.6.15-rc3/drivers/acpi/processor_idle.c (+15 lines)
Lines 929-934 static int acpi_processor_power_verify(s Link Here
929
	unsigned int i;
929
	unsigned int i;
930
	unsigned int working = 0;
930
	unsigned int working = 0;
931
931
932
#ifdef ARCH_APICTIMER_STOPS_ON_C3
933
	struct cpuinfo_x86 *c = cpu_data + pr->id;
934
	cpumask_t mask = cpumask_of_cpu(pr->id);
935
936
	if (c->x86_vendor == X86_VENDOR_INTEL) {
937
		on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
938
	}
939
#endif
940
932
	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
941
	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
933
		struct acpi_processor_cx *cx = &pr->power.states[i];
942
		struct acpi_processor_cx *cx = &pr->power.states[i];
934
943
Lines 943-948 static int acpi_processor_power_verify(s Link Here
943
952
944
		case ACPI_STATE_C3:
953
		case ACPI_STATE_C3:
945
			acpi_processor_power_verify_c3(pr, cx);
954
			acpi_processor_power_verify_c3(pr, cx);
955
#ifdef ARCH_APICTIMER_STOPS_ON_C3
956
			if (c->x86_vendor == X86_VENDOR_INTEL) {
957
				on_each_cpu(switch_APIC_timer_to_ipi, 
958
						&mask, 1, 1);
959
			}
960
#endif
946
			break;
961
			break;
947
		}
962
		}
948
963

Return to bug 2560