summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-06-18 06:54:22 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2015-08-10 05:40:30 -0400
commit8eda41b0863ca82010010e951b7aa13b66a06e78 (patch)
tree266dfb6adecfc7ef64b155e9b8411159d7b70a90
parent737663401897f84610d00552eeb83ffa4d730142 (diff)
clockevents/drivers/i8253: Migrate to new 'set-state' interface
Migrate i8253 driver to the new 'set-state' interface provided by clockevents core, the earlier 'set-mode' interface is marked obsolete now. This also enables us to implement callbacks for new states of clockevent devices, for example: ONESHOT_STOPPED. Cc: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r--arch/x86/kernel/i8253.c2
-rw-r--r--drivers/clocksource/i8253.c77
2 files changed, 39 insertions, 40 deletions
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index f2b96de3c7c1..efb82f07b29c 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -34,7 +34,7 @@ static int __init init_pit_clocksource(void)
34 * - when local APIC timer is active (PIT is switched off) 34 * - when local APIC timer is active (PIT is switched off)
35 */ 35 */
36 if (num_possible_cpus() > 1 || is_hpet_enabled() || 36 if (num_possible_cpus() > 1 || is_hpet_enabled() ||
37 i8253_clockevent.mode != CLOCK_EVT_MODE_PERIODIC) 37 !clockevent_state_periodic(&i8253_clockevent))
38 return 0; 38 return 0;
39 39
40 return clocksource_i8253_init(); 40 return clocksource_i8253_init();
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.