aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/i8253.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource/i8253.c')
-rw-r--r--drivers/clocksource/i8253.c77
1 files changed, 38 insertions, 39 deletions
diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c
index 14ee3efcc404..0efd36e483ab 100644
--- a/drivers/clocksource/i8253.c
+++ b/drivers/clocksource/i8253.c
@@ -100,44 +100,40 @@ int __init clocksource_i8253_init(void)
100#endif 100#endif
101 101
102#ifdef CONFIG_CLKEVT_I8253 102#ifdef CONFIG_CLKEVT_I8253
103/* 103static int pit_shutdown(struct clock_event_device *evt)
104 * Initialize the PIT timer.
105 *
106 * This is also called after resume to bring the PIT into operation again.
107 */
108static void init_pit_timer(enum clock_event_mode mode,
109 struct clock_event_device *evt)
110{ 104{
105 if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt))
106 return 0;
107
111 raw_spin_lock(&i8253_lock); 108 raw_spin_lock(&i8253_lock);
112 109
113 switch (mode) { 110 outb_p(0x30, PIT_MODE);
114 case CLOCK_EVT_MODE_PERIODIC: 111 outb_p(0, PIT_CH0);
115 /* binary, mode 2, LSB/MSB, ch 0 */ 112 outb_p(0, PIT_CH0);
116 outb_p(0x34, PIT_MODE); 113
117 outb_p(PIT_LATCH & 0xff , PIT_CH0); /* LSB */ 114 raw_spin_unlock(&i8253_lock);
118 outb_p(PIT_LATCH >> 8 , PIT_CH0); /* MSB */ 115 return 0;
119 break; 116}
120 117
121 case CLOCK_EVT_MODE_SHUTDOWN: 118static int pit_set_oneshot(struct clock_event_device *evt)
122 case CLOCK_EVT_MODE_UNUSED: 119{
123 if (evt->mode == CLOCK_EVT_MODE_PERIODIC || 120 raw_spin_lock(&i8253_lock);
124 evt->mode == CLOCK_EVT_MODE_ONESHOT) { 121 outb_p(0x38, PIT_MODE);
125 outb_p(0x30, PIT_MODE); 122 raw_spin_unlock(&i8253_lock);
126 outb_p(0, PIT_CH0); 123 return 0;
127 outb_p(0, PIT_CH0); 124}
128 } 125
129 break; 126static int pit_set_periodic(struct clock_event_device *evt)
130 127{
131 case CLOCK_EVT_MODE_ONESHOT: 128 raw_spin_lock(&i8253_lock);
132 /* One shot setup */ 129
133 outb_p(0x38, PIT_MODE); 130 /* binary, mode 2, LSB/MSB, ch 0 */
134 break; 131 outb_p(0x34, PIT_MODE);
135 132 outb_p(PIT_LATCH & 0xff, PIT_CH0); /* LSB */
136 case CLOCK_EVT_MODE_RESUME: 133 outb_p(PIT_LATCH >> 8, PIT_CH0); /* MSB */
137 /* Nothing to do here */ 134
138 break;
139 }
140 raw_spin_unlock(&i8253_lock); 135 raw_spin_unlock(&i8253_lock);
136 return 0;
141} 137}
142 138
143/* 139/*
@@ -160,10 +156,11 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
160 * it can be solely used for the global tick. 156 * it can be solely used for the global tick.
161 */ 157 */
162struct clock_event_device i8253_clockevent = { 158struct clock_event_device i8253_clockevent = {
163 .name = "pit", 159 .name = "pit",
164 .features = CLOCK_EVT_FEAT_PERIODIC, 160 .features = CLOCK_EVT_FEAT_PERIODIC,
165 .set_mode = init_pit_timer, 161 .set_state_shutdown = pit_shutdown,
166 .set_next_event = pit_next_event, 162 .set_state_periodic = pit_set_periodic,
163 .set_next_event = pit_next_event,
167}; 164};
168 165
169/* 166/*
@@ -172,8 +169,10 @@ struct clock_event_device i8253_clockevent = {
172 */ 169 */
173void __init clockevent_i8253_init(bool oneshot) 170void __init clockevent_i8253_init(bool oneshot)
174{ 171{
175 if (oneshot) 172 if (oneshot) {
176 i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT; 173 i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT;
174 i8253_clockevent.set_state_oneshot = pit_set_oneshot;
175 }
177 /* 176 /*
178 * Start pit with the boot cpu mask. x86 might make it global 177 * Start pit with the boot cpu mask. x86 might make it global
179 * when it is used as broadcast device later. 178 * when it is used as broadcast device later.