aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/apic_64.c79
-rw-r--r--arch/x86_64/Kconfig6
2 files changed, 85 insertions, 0 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 40938ef99dc2..2c2807abe1d4 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -25,6 +25,7 @@
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/clockchips.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/smp.h> 31#include <asm/smp.h>
@@ -57,6 +58,77 @@ static struct resource lapic_resource = {
57 58
58static unsigned int calibration_result; 59static unsigned int calibration_result;
59 60
61static int lapic_next_event(unsigned long delta,
62 struct clock_event_device *evt);
63static void lapic_timer_setup(enum clock_event_mode mode,
64 struct clock_event_device *evt);
65
66static void lapic_timer_broadcast(cpumask_t mask);
67
68static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen);
69
70static struct clock_event_device lapic_clockevent = {
71 .name = "lapic",
72 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
73 | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
74 .shift = 32,
75 .set_mode = lapic_timer_setup,
76 .set_next_event = lapic_next_event,
77 .broadcast = lapic_timer_broadcast,
78 .rating = 100,
79 .irq = -1,
80};
81static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
82
83static int lapic_next_event(unsigned long delta,
84 struct clock_event_device *evt)
85{
86 apic_write(APIC_TMICT, delta);
87 return 0;
88}
89
90static void lapic_timer_setup(enum clock_event_mode mode,
91 struct clock_event_device *evt)
92{
93 unsigned long flags;
94 unsigned int v;
95
96 /* Lapic used as dummy for broadcast ? */
97 if (evt->features & CLOCK_EVT_FEAT_DUMMY)
98 return;
99
100 local_irq_save(flags);
101
102 switch (mode) {
103 case CLOCK_EVT_MODE_PERIODIC:
104 case CLOCK_EVT_MODE_ONESHOT:
105 __setup_APIC_LVTT(calibration_result,
106 mode != CLOCK_EVT_MODE_PERIODIC, 1);
107 break;
108 case CLOCK_EVT_MODE_UNUSED:
109 case CLOCK_EVT_MODE_SHUTDOWN:
110 v = apic_read(APIC_LVTT);
111 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
112 apic_write(APIC_LVTT, v);
113 break;
114 case CLOCK_EVT_MODE_RESUME:
115 /* Nothing to do here */
116 break;
117 }
118
119 local_irq_restore(flags);
120}
121
122/*
123 * Local APIC timer broadcast function
124 */
125static void lapic_timer_broadcast(cpumask_t mask)
126{
127#ifdef CONFIG_SMP
128 send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
129#endif
130}
131
60/* 132/*
61 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as 133 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
62 * IPIs in place of local APIC timers 134 * IPIs in place of local APIC timers
@@ -866,6 +938,13 @@ static void __init calibrate_APIC_clock(void)
866 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", 938 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
867 result / 1000 / 1000, result / 1000 % 1000); 939 result / 1000 / 1000, result / 1000 % 1000);
868 940
941 /* Calculate the scaled math multiplication factor */
942 lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32);
943 lapic_clockevent.max_delta_ns =
944 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
945 lapic_clockevent.min_delta_ns =
946 clockevent_delta2ns(0xF, &lapic_clockevent);
947
869 calibration_result = result / HZ; 948 calibration_result = result / HZ;
870} 949}
871 950
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 520f33b83bfc..a9534c21c306 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -40,6 +40,10 @@ config CLOCKSOURCE_WATCHDOG
40 bool 40 bool
41 default y 41 default y
42 42
43config GENERIC_CLOCKEVENTS_MIGR
44 bool
45 default y
46
43config ZONE_DMA32 47config ZONE_DMA32
44 bool 48 bool
45 default y 49 default y
@@ -134,6 +138,8 @@ source "init/Kconfig"
134 138
135menu "Processor type and features" 139menu "Processor type and features"
136 140
141source "kernel/time/Kconfig"
142
137choice 143choice
138 prompt "Subarchitecture Type" 144 prompt "Subarchitecture Type"
139 default X86_PC 145 default X86_PC