aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/kernel/time.c18
-rw-r--r--arch/blackfin/kernel/time-ts.c136
-rw-r--r--arch/c6x/platforms/timer64.c52
-rw-r--r--arch/cris/arch-v32/kernel/time.c8
-rw-r--r--arch/microblaze/kernel/timer.c46
-rw-r--r--arch/mn10300/kernel/cevt-mn10300.c7
-rw-r--r--arch/openrisc/kernel/time.c24
-rw-r--r--arch/powerpc/kernel/time.c24
-rw-r--r--arch/s390/kernel/time.c6
-rw-r--r--arch/score/kernel/time.c31
-rw-r--r--arch/sh/kernel/localtimer.c6
-rw-r--r--arch/sparc/kernel/sun4m_smp.c2
-rw-r--r--arch/sparc/kernel/time_32.c57
-rw-r--r--arch/sparc/kernel/time_64.c33
-rw-r--r--arch/um/kernel/time.c44
-rw-r--r--arch/unicore32/kernel/time.c29
-rw-r--r--arch/x86/kernel/i8253.c2
-rw-r--r--arch/xtensa/kernel/time.c53
-rw-r--r--drivers/clocksource/Kconfig2
-rw-r--r--drivers/clocksource/arm_arch_timer.c52
-rw-r--r--drivers/clocksource/arm_global_timer.c37
-rw-r--r--drivers/clocksource/asm9260_timer.c64
-rw-r--r--drivers/clocksource/bcm2835_timer.c16
-rw-r--r--drivers/clocksource/bcm_kona_timer.c17
-rw-r--r--drivers/clocksource/cadence_ttc_timer.c59
-rw-r--r--drivers/clocksource/clps711x-timer.c6
-rw-r--r--drivers/clocksource/cs5535-clockevt.c24
-rw-r--r--drivers/clocksource/dummy_timer.c10
-rw-r--r--drivers/clocksource/dw_apb_timer.c146
-rw-r--r--drivers/clocksource/em_sti.c39
-rw-r--r--drivers/clocksource/exynos_mct.c101
-rw-r--r--drivers/clocksource/fsl_ftm_timer.c35
-rw-r--r--drivers/clocksource/h8300_timer8.c51
-rw-r--r--drivers/clocksource/i8253.c77
-rw-r--r--drivers/clocksource/meson6_timer.c50
-rw-r--r--drivers/clocksource/metag_generic.c20
-rw-r--r--drivers/clocksource/mips-gic-timer.c7
-rw-r--r--drivers/clocksource/moxart_timer.c49
-rw-r--r--drivers/clocksource/mtk_timer.c32
-rw-r--r--drivers/clocksource/mxs_timer.c80
-rw-r--r--drivers/clocksource/nomadik-mtu.c58
-rw-r--r--drivers/clocksource/pxa_timer.c39
-rw-r--r--drivers/clocksource/qcom-timer.c24
-rw-r--r--drivers/clocksource/rockchip_timer.c32
-rw-r--r--drivers/clocksource/samsung_pwm_timer.c41
-rw-r--r--drivers/clocksource/sh_cmt.c65
-rw-r--r--drivers/clocksource/sh_mtu2.c42
-rw-r--r--drivers/clocksource/sh_tmu.c64
-rw-r--r--drivers/clocksource/sun4i_timer.c41
-rw-r--r--drivers/clocksource/tcb_clksrc.c93
-rw-r--r--drivers/clocksource/tegra20_timer.c45
-rw-r--r--drivers/clocksource/time-armada-370-xp.c53
-rw-r--r--drivers/clocksource/time-efm32.c66
-rw-r--r--drivers/clocksource/time-orion.c46
-rw-r--r--drivers/clocksource/timer-atlas7.c19
-rw-r--r--drivers/clocksource/timer-atmel-pit.c45
-rw-r--r--drivers/clocksource/timer-atmel-st.c69
-rw-r--r--drivers/clocksource/timer-digicolor.c41
-rw-r--r--drivers/clocksource/timer-imx-gpt.c75
-rw-r--r--drivers/clocksource/timer-integrator-ap.c58
-rw-r--r--drivers/clocksource/timer-keystone.c44
-rw-r--r--drivers/clocksource/timer-prima2.c34
-rw-r--r--drivers/clocksource/timer-sp804.c54
-rw-r--r--drivers/clocksource/timer-stm32.c30
-rw-r--r--drivers/clocksource/timer-sun5i.c45
-rw-r--r--drivers/clocksource/timer-u300.c155
-rw-r--r--drivers/clocksource/vf_pit_timer.c27
-rw-r--r--drivers/clocksource/vt8500_timer.c29
-rw-r--r--drivers/clocksource/zevio-timer.c44
-rw-r--r--include/linux/clockchips.h3
-rw-r--r--include/linux/jiffies.h22
-rw-r--r--include/linux/time64.h35
-rw-r--r--include/linux/timekeeping.h9
-rw-r--r--kernel/time/hrtimer.c36
-rw-r--r--kernel/time/ntp.c5
-rw-r--r--kernel/time/tick-broadcast-hrtimer.c49
-rw-r--r--kernel/time/tick-common.c3
-rw-r--r--kernel/time/time.c43
-rw-r--r--kernel/time/timekeeping.c19
-rw-r--r--kernel/time/timer_list.c2
80 files changed, 1575 insertions, 1681 deletions
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 643a9dcdf093..5b6202a825ff 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -93,7 +93,7 @@ rtc_timer_interrupt(int irq, void *dev)
93 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); 93 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
94 94
95 /* Don't run the hook for UNUSED or SHUTDOWN. */ 95 /* Don't run the hook for UNUSED or SHUTDOWN. */
96 if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC)) 96 if (likely(clockevent_state_periodic(ce)))
97 ce->event_handler(ce); 97 ce->event_handler(ce);
98 98
99 if (test_irq_work_pending()) { 99 if (test_irq_work_pending()) {
@@ -104,13 +104,6 @@ rtc_timer_interrupt(int irq, void *dev)
104 return IRQ_HANDLED; 104 return IRQ_HANDLED;
105} 105}
106 106
107static void
108rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
109{
110 /* The mode member of CE is updated in generic code.
111 Since we only support periodic events, nothing to do. */
112}
113
114static int 107static int
115rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) 108rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
116{ 109{
@@ -129,7 +122,6 @@ init_rtc_clockevent(void)
129 .features = CLOCK_EVT_FEAT_PERIODIC, 122 .features = CLOCK_EVT_FEAT_PERIODIC,
130 .rating = 100, 123 .rating = 100,
131 .cpumask = cpumask_of(cpu), 124 .cpumask = cpumask_of(cpu),
132 .set_mode = rtc_ce_set_mode,
133 .set_next_event = rtc_ce_set_next_event, 125 .set_next_event = rtc_ce_set_next_event,
134 }; 126 };
135 127
@@ -161,12 +153,12 @@ static struct clocksource qemu_cs = {
161 * The QEMU alarm as a clock_event_device primitive. 153 * The QEMU alarm as a clock_event_device primitive.
162 */ 154 */
163 155
164static void 156static int qemu_ce_shutdown(struct clock_event_device *ce)
165qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
166{ 157{
167 /* The mode member of CE is updated for us in generic code. 158 /* The mode member of CE is updated for us in generic code.
168 Just make sure that the event is disabled. */ 159 Just make sure that the event is disabled. */
169 qemu_set_alarm_abs(0); 160 qemu_set_alarm_abs(0);
161 return 0;
170} 162}
171 163
172static int 164static int
@@ -197,7 +189,9 @@ init_qemu_clockevent(void)
197 .features = CLOCK_EVT_FEAT_ONESHOT, 189 .features = CLOCK_EVT_FEAT_ONESHOT,
198 .rating = 400, 190 .rating = 400,
199 .cpumask = cpumask_of(cpu), 191 .cpumask = cpumask_of(cpu),
200 .set_mode = qemu_ce_set_mode, 192 .set_state_shutdown = qemu_ce_shutdown,
193 .set_state_oneshot = qemu_ce_shutdown,
194 .tick_resume = qemu_ce_shutdown,
201 .set_next_event = qemu_ce_set_next_event, 195 .set_next_event = qemu_ce_set_next_event,
202 }; 196 };
203 197
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index cb0a4845339e..fb9e95f1b719 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -136,44 +136,44 @@ static int bfin_gptmr0_set_next_event(unsigned long cycles,
136 return 0; 136 return 0;
137} 137}
138 138
139static void bfin_gptmr0_set_mode(enum clock_event_mode mode, 139static int bfin_gptmr0_set_periodic(struct clock_event_device *evt)
140 struct clock_event_device *evt)
141{ 140{
142 switch (mode) {
143 case CLOCK_EVT_MODE_PERIODIC: {
144#ifndef CONFIG_BF60x 141#ifndef CONFIG_BF60x
145 set_gptimer_config(TIMER0_id, \ 142 set_gptimer_config(TIMER0_id,
146 TIMER_OUT_DIS | TIMER_IRQ_ENA | \ 143 TIMER_OUT_DIS | TIMER_IRQ_ENA |
147 TIMER_PERIOD_CNT | TIMER_MODE_PWM); 144 TIMER_PERIOD_CNT | TIMER_MODE_PWM);
148#else 145#else
149 set_gptimer_config(TIMER0_id, TIMER_OUT_DIS 146 set_gptimer_config(TIMER0_id,
150 | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); 147 TIMER_OUT_DIS | TIMER_MODE_PWM_CONT |
148 TIMER_PULSE_HI | TIMER_IRQ_PER);
151#endif 149#endif
152 150
153 set_gptimer_period(TIMER0_id, get_sclk() / HZ); 151 set_gptimer_period(TIMER0_id, get_sclk() / HZ);
154 set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); 152 set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);
155 enable_gptimers(TIMER0bit); 153 enable_gptimers(TIMER0bit);
156 break; 154 return 0;
157 } 155}
158 case CLOCK_EVT_MODE_ONESHOT: 156
159 disable_gptimers(TIMER0bit); 157static int bfin_gptmr0_set_oneshot(struct clock_event_device *evt)
158{
159 disable_gptimers(TIMER0bit);
160#ifndef CONFIG_BF60x 160#ifndef CONFIG_BF60x
161 set_gptimer_config(TIMER0_id, \ 161 set_gptimer_config(TIMER0_id,
162 TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); 162 TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM);
163#else 163#else
164 set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM 164 set_gptimer_config(TIMER0_id,
165 | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); 165 TIMER_OUT_DIS | TIMER_MODE_PWM | TIMER_PULSE_HI |
166 TIMER_IRQ_WID_DLY);
166#endif 167#endif
167 168
168 set_gptimer_period(TIMER0_id, 0); 169 set_gptimer_period(TIMER0_id, 0);
169 break; 170 return 0;
170 case CLOCK_EVT_MODE_UNUSED: 171}
171 case CLOCK_EVT_MODE_SHUTDOWN: 172
172 disable_gptimers(TIMER0bit); 173static int bfin_gptmr0_shutdown(struct clock_event_device *evt)
173 break; 174{
174 case CLOCK_EVT_MODE_RESUME: 175 disable_gptimers(TIMER0bit);
175 break; 176 return 0;
176 }
177} 177}
178 178
179static void bfin_gptmr0_ack(void) 179static void bfin_gptmr0_ack(void)
@@ -211,13 +211,16 @@ static struct irqaction gptmr0_irq = {
211}; 211};
212 212
213static struct clock_event_device clockevent_gptmr0 = { 213static struct clock_event_device clockevent_gptmr0 = {
214 .name = "bfin_gptimer0", 214 .name = "bfin_gptimer0",
215 .rating = 300, 215 .rating = 300,
216 .irq = IRQ_TIMER0, 216 .irq = IRQ_TIMER0,
217 .shift = 32, 217 .shift = 32,
218 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 218 .features = CLOCK_EVT_FEAT_PERIODIC |
219 .set_next_event = bfin_gptmr0_set_next_event, 219 CLOCK_EVT_FEAT_ONESHOT,
220 .set_mode = bfin_gptmr0_set_mode, 220 .set_next_event = bfin_gptmr0_set_next_event,
221 .set_state_shutdown = bfin_gptmr0_shutdown,
222 .set_state_periodic = bfin_gptmr0_set_periodic,
223 .set_state_oneshot = bfin_gptmr0_set_oneshot,
221}; 224};
222 225
223static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt) 226static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
@@ -250,36 +253,35 @@ static int bfin_coretmr_set_next_event(unsigned long cycles,
250 return 0; 253 return 0;
251} 254}
252 255
253static void bfin_coretmr_set_mode(enum clock_event_mode mode, 256static int bfin_coretmr_set_periodic(struct clock_event_device *evt)
254 struct clock_event_device *evt)
255{ 257{
256 switch (mode) { 258 unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
257 case CLOCK_EVT_MODE_PERIODIC: { 259
258 unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1); 260 bfin_write_TCNTL(TMPWR);
259 bfin_write_TCNTL(TMPWR); 261 CSYNC();
260 CSYNC(); 262 bfin_write_TSCALE(TIME_SCALE - 1);
261 bfin_write_TSCALE(TIME_SCALE - 1); 263 bfin_write_TPERIOD(tcount);
262 bfin_write_TPERIOD(tcount); 264 bfin_write_TCOUNT(tcount);
263 bfin_write_TCOUNT(tcount); 265 CSYNC();
264 CSYNC(); 266 bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD);
265 bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD); 267 return 0;
266 break; 268}
267 } 269
268 case CLOCK_EVT_MODE_ONESHOT: 270static int bfin_coretmr_set_oneshot(struct clock_event_device *evt)
269 bfin_write_TCNTL(TMPWR); 271{
270 CSYNC(); 272 bfin_write_TCNTL(TMPWR);
271 bfin_write_TSCALE(TIME_SCALE - 1); 273 CSYNC();
272 bfin_write_TPERIOD(0); 274 bfin_write_TSCALE(TIME_SCALE - 1);
273 bfin_write_TCOUNT(0); 275 bfin_write_TPERIOD(0);
274 break; 276 bfin_write_TCOUNT(0);
275 case CLOCK_EVT_MODE_UNUSED: 277 return 0;
276 case CLOCK_EVT_MODE_SHUTDOWN: 278}
277 bfin_write_TCNTL(0); 279
278 CSYNC(); 280static int bfin_coretmr_shutdown(struct clock_event_device *evt)
279 break; 281{
280 case CLOCK_EVT_MODE_RESUME: 282 bfin_write_TCNTL(0);
281 break; 283 CSYNC();
282 } 284 return 0;
283} 285}
284 286
285void bfin_coretmr_init(void) 287void bfin_coretmr_init(void)
@@ -335,7 +337,9 @@ void bfin_coretmr_clockevent_init(void)
335 evt->shift = 32; 337 evt->shift = 32;
336 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 338 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
337 evt->set_next_event = bfin_coretmr_set_next_event; 339 evt->set_next_event = bfin_coretmr_set_next_event;
338 evt->set_mode = bfin_coretmr_set_mode; 340 evt->set_state_shutdown = bfin_coretmr_shutdown;
341 evt->set_state_periodic = bfin_coretmr_set_periodic;
342 evt->set_state_oneshot = bfin_coretmr_set_oneshot;
339 343
340 clock_tick = get_cclk() / TIME_SCALE; 344 clock_tick = get_cclk() / TIME_SCALE;
341 evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); 345 evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c
index 3c73d74a4674..c19901e5f055 100644
--- a/arch/c6x/platforms/timer64.c
+++ b/arch/c6x/platforms/timer64.c
@@ -126,35 +126,37 @@ static int next_event(unsigned long delta,
126 return 0; 126 return 0;
127} 127}
128 128
129static void set_clock_mode(enum clock_event_mode mode, 129static int set_periodic(struct clock_event_device *evt)
130 struct clock_event_device *evt)
131{ 130{
132 switch (mode) { 131 timer64_enable();
133 case CLOCK_EVT_MODE_PERIODIC: 132 timer64_mode = TIMER64_MODE_PERIODIC;
134 timer64_enable(); 133 timer64_config(TIMER64_RATE / HZ);
135 timer64_mode = TIMER64_MODE_PERIODIC; 134 return 0;
136 timer64_config(TIMER64_RATE / HZ); 135}
137 break; 136
138 case CLOCK_EVT_MODE_ONESHOT: 137static int set_oneshot(struct clock_event_device *evt)
139 timer64_enable(); 138{
140 timer64_mode = TIMER64_MODE_ONE_SHOT; 139 timer64_enable();
141 break; 140 timer64_mode = TIMER64_MODE_ONE_SHOT;
142 case CLOCK_EVT_MODE_UNUSED: 141 return 0;
143 case CLOCK_EVT_MODE_SHUTDOWN: 142}
144 timer64_mode = TIMER64_MODE_DISABLED; 143
145 timer64_disable(); 144static int shutdown(struct clock_event_device *evt)
146 break; 145{
147 case CLOCK_EVT_MODE_RESUME: 146 timer64_mode = TIMER64_MODE_DISABLED;
148 break; 147 timer64_disable();
149 } 148 return 0;
150} 149}
151 150
152static struct clock_event_device t64_clockevent_device = { 151static struct clock_event_device t64_clockevent_device = {
153 .name = "TIMER64_EVT32_TIMER", 152 .name = "TIMER64_EVT32_TIMER",
154 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 153 .features = CLOCK_EVT_FEAT_ONESHOT |
155 .rating = 200, 154 CLOCK_EVT_FEAT_PERIODIC,
156 .set_mode = set_clock_mode, 155 .rating = 200,
157 .set_next_event = next_event, 156 .set_state_shutdown = shutdown,
157 .set_state_periodic = set_periodic,
158 .set_state_oneshot = set_oneshot,
159 .set_next_event = next_event,
158}; 160};
159 161
160static irqreturn_t timer_interrupt(int irq, void *dev_id) 162static irqreturn_t timer_interrupt(int irq, void *dev_id)
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 4fce9f1f7cc0..d2a84407654a 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -172,8 +172,7 @@ void handle_watchdog_bite(struct pt_regs *regs)
172extern void cris_profile_sample(struct pt_regs *regs); 172extern void cris_profile_sample(struct pt_regs *regs);
173static void __iomem *timer_base; 173static void __iomem *timer_base;
174 174
175static void crisv32_clkevt_mode(enum clock_event_mode mode, 175static int crisv32_clkevt_switch_state(struct clock_event_device *dev)
176 struct clock_event_device *dev)
177{ 176{
178 reg_timer_rw_tmr0_ctrl ctrl = { 177 reg_timer_rw_tmr0_ctrl ctrl = {
179 .op = regk_timer_hold, 178 .op = regk_timer_hold,
@@ -181,6 +180,7 @@ static void crisv32_clkevt_mode(enum clock_event_mode mode,
181 }; 180 };
182 181
183 REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); 182 REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl);
183 return 0;
184} 184}
185 185
186static int crisv32_clkevt_next_event(unsigned long evt, 186static int crisv32_clkevt_next_event(unsigned long evt,
@@ -231,7 +231,9 @@ static struct clock_event_device crisv32_clockevent = {
231 .name = "crisv32-timer", 231 .name = "crisv32-timer",
232 .rating = 300, 232 .rating = 300,
233 .features = CLOCK_EVT_FEAT_ONESHOT, 233 .features = CLOCK_EVT_FEAT_ONESHOT,
234 .set_mode = crisv32_clkevt_mode, 234 .set_state_oneshot = crisv32_clkevt_switch_state,
235 .set_state_shutdown = crisv32_clkevt_switch_state,
236 .tick_resume = crisv32_clkevt_switch_state,
235 .set_next_event = crisv32_clkevt_next_event, 237 .set_next_event = crisv32_clkevt_next_event,
236}; 238};
237 239
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index c8977450e28c..67e2ef48d2d0 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -122,37 +122,29 @@ static int xilinx_timer_set_next_event(unsigned long delta,
122 return 0; 122 return 0;
123} 123}
124 124
125static void xilinx_timer_set_mode(enum clock_event_mode mode, 125static int xilinx_timer_shutdown(struct clock_event_device *evt)
126 struct clock_event_device *evt)
127{ 126{
128 switch (mode) { 127 pr_info("%s\n", __func__);
129 case CLOCK_EVT_MODE_PERIODIC: 128 xilinx_timer0_stop();
130 pr_info("%s: periodic\n", __func__); 129 return 0;
131 xilinx_timer0_start_periodic(freq_div_hz); 130}
132 break; 131
133 case CLOCK_EVT_MODE_ONESHOT: 132static int xilinx_timer_set_periodic(struct clock_event_device *evt)
134 pr_info("%s: oneshot\n", __func__); 133{
135 break; 134 pr_info("%s\n", __func__);
136 case CLOCK_EVT_MODE_UNUSED: 135 xilinx_timer0_start_periodic(freq_div_hz);
137 pr_info("%s: unused\n", __func__); 136 return 0;
138 break;
139 case CLOCK_EVT_MODE_SHUTDOWN:
140 pr_info("%s: shutdown\n", __func__);
141 xilinx_timer0_stop();
142 break;
143 case CLOCK_EVT_MODE_RESUME:
144 pr_info("%s: resume\n", __func__);
145 break;
146 }
147} 137}
148 138
149static struct clock_event_device clockevent_xilinx_timer = { 139static struct clock_event_device clockevent_xilinx_timer = {
150 .name = "xilinx_clockevent", 140 .name = "xilinx_clockevent",
151 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 141 .features = CLOCK_EVT_FEAT_ONESHOT |
152 .shift = 8, 142 CLOCK_EVT_FEAT_PERIODIC,
153 .rating = 300, 143 .shift = 8,
154 .set_next_event = xilinx_timer_set_next_event, 144 .rating = 300,
155 .set_mode = xilinx_timer_set_mode, 145 .set_next_event = xilinx_timer_set_next_event,
146 .set_state_shutdown = xilinx_timer_shutdown,
147 .set_state_periodic = xilinx_timer_set_periodic,
156}; 148};
157 149
158static inline void timer_ack(void) 150static inline void timer_ack(void)
diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
index 60f64ca1752a..3aae9f5a98aa 100644
--- a/arch/mn10300/kernel/cevt-mn10300.c
+++ b/arch/mn10300/kernel/cevt-mn10300.c
@@ -41,12 +41,6 @@ static int next_event(unsigned long delta,
41 return 0; 41 return 0;
42} 42}
43 43
44static void set_clock_mode(enum clock_event_mode mode,
45 struct clock_event_device *evt)
46{
47 /* Nothing to do ... */
48}
49
50static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device); 44static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device);
51static DEFINE_PER_CPU(struct irqaction, timer_irq); 45static DEFINE_PER_CPU(struct irqaction, timer_irq);
52 46
@@ -108,7 +102,6 @@ int __init init_clockevents(void)
108 102
109 cd->rating = 200; 103 cd->rating = 200;
110 cd->cpumask = cpumask_of(smp_processor_id()); 104 cd->cpumask = cpumask_of(smp_processor_id());
111 cd->set_mode = set_clock_mode;
112 cd->event_handler = event_handler; 105 cd->event_handler = event_handler;
113 cd->set_next_event = next_event; 106 cd->set_next_event = next_event;
114 107
diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c
index 7c52e9494a8d..50e970183dcd 100644
--- a/arch/openrisc/kernel/time.c
+++ b/arch/openrisc/kernel/time.c
@@ -48,29 +48,6 @@ static int openrisc_timer_set_next_event(unsigned long delta,
48 return 0; 48 return 0;
49} 49}
50 50
51static void openrisc_timer_set_mode(enum clock_event_mode mode,
52 struct clock_event_device *evt)
53{
54 switch (mode) {
55 case CLOCK_EVT_MODE_PERIODIC:
56 pr_debug(KERN_INFO "%s: periodic\n", __func__);
57 BUG();
58 break;
59 case CLOCK_EVT_MODE_ONESHOT:
60 pr_debug(KERN_INFO "%s: oneshot\n", __func__);
61 break;
62 case CLOCK_EVT_MODE_UNUSED:
63 pr_debug(KERN_INFO "%s: unused\n", __func__);
64 break;
65 case CLOCK_EVT_MODE_SHUTDOWN:
66 pr_debug(KERN_INFO "%s: shutdown\n", __func__);
67 break;
68 case CLOCK_EVT_MODE_RESUME:
69 pr_debug(KERN_INFO "%s: resume\n", __func__);
70 break;
71 }
72}
73
74/* This is the clock event device based on the OR1K tick timer. 51/* This is the clock event device based on the OR1K tick timer.
75 * As the timer is being used as a continuous clock-source (required for HR 52 * As the timer is being used as a continuous clock-source (required for HR
76 * timers) we cannot enable the PERIODIC feature. The tick timer can run using 53 * timers) we cannot enable the PERIODIC feature. The tick timer can run using
@@ -82,7 +59,6 @@ static struct clock_event_device clockevent_openrisc_timer = {
82 .features = CLOCK_EVT_FEAT_ONESHOT, 59 .features = CLOCK_EVT_FEAT_ONESHOT,
83 .rating = 300, 60 .rating = 300,
84 .set_next_event = openrisc_timer_set_next_event, 61 .set_next_event = openrisc_timer_set_next_event,
85 .set_mode = openrisc_timer_set_mode,
86}; 62};
87 63
88static inline void timer_ack(void) 64static inline void timer_ack(void)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 43922509a483..1be1092c7204 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -99,16 +99,17 @@ static struct clocksource clocksource_timebase = {
99 99
100static int decrementer_set_next_event(unsigned long evt, 100static int decrementer_set_next_event(unsigned long evt,
101 struct clock_event_device *dev); 101 struct clock_event_device *dev);
102static void decrementer_set_mode(enum clock_event_mode mode, 102static int decrementer_shutdown(struct clock_event_device *evt);
103 struct clock_event_device *dev);
104 103
105struct clock_event_device decrementer_clockevent = { 104struct clock_event_device decrementer_clockevent = {
106 .name = "decrementer", 105 .name = "decrementer",
107 .rating = 200, 106 .rating = 200,
108 .irq = 0, 107 .irq = 0,
109 .set_next_event = decrementer_set_next_event, 108 .set_next_event = decrementer_set_next_event,
110 .set_mode = decrementer_set_mode, 109 .set_state_shutdown = decrementer_shutdown,
111 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP, 110 .tick_resume = decrementer_shutdown,
111 .features = CLOCK_EVT_FEAT_ONESHOT |
112 CLOCK_EVT_FEAT_C3STOP,
112}; 113};
113EXPORT_SYMBOL(decrementer_clockevent); 114EXPORT_SYMBOL(decrementer_clockevent);
114 115
@@ -862,11 +863,10 @@ static int decrementer_set_next_event(unsigned long evt,
862 return 0; 863 return 0;
863} 864}
864 865
865static void decrementer_set_mode(enum clock_event_mode mode, 866static int decrementer_shutdown(struct clock_event_device *dev)
866 struct clock_event_device *dev)
867{ 867{
868 if (mode != CLOCK_EVT_MODE_ONESHOT) 868 decrementer_set_next_event(DECREMENTER_MAX, dev);
869 decrementer_set_next_event(DECREMENTER_MAX, dev); 869 return 0;
870} 870}
871 871
872/* Interrupt handler for the timer broadcast IPI */ 872/* Interrupt handler for the timer broadcast IPI */
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 627887b075a7..52524b9083c3 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -120,11 +120,6 @@ static int s390_next_event(unsigned long delta,
120 return 0; 120 return 0;
121} 121}
122 122
123static void s390_set_mode(enum clock_event_mode mode,
124 struct clock_event_device *evt)
125{
126}
127
128/* 123/*
129 * Set up lowcore and control register of the current cpu to 124 * Set up lowcore and control register of the current cpu to
130 * enable TOD clock and clock comparator interrupts. 125 * enable TOD clock and clock comparator interrupts.
@@ -148,7 +143,6 @@ void init_cpu_timer(void)
148 cd->rating = 400; 143 cd->rating = 400;
149 cd->cpumask = cpumask_of(cpu); 144 cd->cpumask = cpumask_of(cpu);
150 cd->set_next_event = s390_next_event; 145 cd->set_next_event = s390_next_event;
151 cd->set_mode = s390_set_mode;
152 146
153 clockevents_register_device(cd); 147 clockevents_register_device(cd);
154 148
diff --git a/arch/score/kernel/time.c b/arch/score/kernel/time.c
index 24770cd9b473..679b8d7b0350 100644
--- a/arch/score/kernel/time.c
+++ b/arch/score/kernel/time.c
@@ -55,31 +55,20 @@ static int score_timer_set_next_event(unsigned long delta,
55 return 0; 55 return 0;
56} 56}
57 57
58static void score_timer_set_mode(enum clock_event_mode mode, 58static int score_timer_set_periodic(struct clock_event_device *evt)
59 struct clock_event_device *evdev)
60{ 59{
61 switch (mode) { 60 outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
62 case CLOCK_EVT_MODE_PERIODIC: 61 outl(SYSTEM_CLOCK / HZ, P_TIMER0_PRELOAD);
63 outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL); 62 outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
64 outl(SYSTEM_CLOCK/HZ, P_TIMER0_PRELOAD); 63 return 0;
65 outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
66 break;
67 case CLOCK_EVT_MODE_ONESHOT:
68 case CLOCK_EVT_MODE_SHUTDOWN:
69 case CLOCK_EVT_MODE_RESUME:
70 case CLOCK_EVT_MODE_UNUSED:
71 break;
72 default:
73 BUG();
74 }
75} 64}
76 65
77static struct clock_event_device score_clockevent = { 66static struct clock_event_device score_clockevent = {
78 .name = "score_clockevent", 67 .name = "score_clockevent",
79 .features = CLOCK_EVT_FEAT_PERIODIC, 68 .features = CLOCK_EVT_FEAT_PERIODIC,
80 .shift = 16, 69 .shift = 16,
81 .set_next_event = score_timer_set_next_event, 70 .set_next_event = score_timer_set_next_event,
82 .set_mode = score_timer_set_mode, 71 .set_state_periodic = score_timer_set_periodic,
83}; 72};
84 73
85void __init time_init(void) 74void __init time_init(void)
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
index b880a7e2ace7..cbb7d4636ec0 100644
--- a/arch/sh/kernel/localtimer.c
+++ b/arch/sh/kernel/localtimer.c
@@ -39,11 +39,6 @@ void local_timer_interrupt(void)
39 irq_exit(); 39 irq_exit();
40} 40}
41 41
42static void dummy_timer_set_mode(enum clock_event_mode mode,
43 struct clock_event_device *clk)
44{
45}
46
47void local_timer_setup(unsigned int cpu) 42void local_timer_setup(unsigned int cpu)
48{ 43{
49 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); 44 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
@@ -54,7 +49,6 @@ void local_timer_setup(unsigned int cpu)
54 CLOCK_EVT_FEAT_DUMMY; 49 CLOCK_EVT_FEAT_DUMMY;
55 clk->rating = 400; 50 clk->rating = 400;
56 clk->mult = 1; 51 clk->mult = 1;
57 clk->set_mode = dummy_timer_set_mode;
58 clk->broadcast = smp_timer_broadcast; 52 clk->broadcast = smp_timer_broadcast;
59 clk->cpumask = cpumask_of(cpu); 53 clk->cpumask = cpumask_of(cpu);
60 54
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index d3408e72d20c..278c40abce82 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -247,7 +247,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
247 247
248 ce = &per_cpu(sparc32_clockevent, cpu); 248 ce = &per_cpu(sparc32_clockevent, cpu);
249 249
250 if (ce->mode & CLOCK_EVT_MODE_PERIODIC) 250 if (clockevent_state_periodic(ce))
251 sun4m_clear_profile_irq(cpu); 251 sun4m_clear_profile_irq(cpu);
252 else 252 else
253 sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */ 253 sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index c9692f387cee..1affabc96b08 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -101,21 +101,18 @@ irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
101 return IRQ_HANDLED; 101 return IRQ_HANDLED;
102} 102}
103 103
104static void timer_ce_set_mode(enum clock_event_mode mode, 104static int timer_ce_shutdown(struct clock_event_device *evt)
105 struct clock_event_device *evt)
106{ 105{
107 switch (mode) { 106 timer_ce_enabled = 0;
108 case CLOCK_EVT_MODE_PERIODIC: 107 smp_mb();
109 case CLOCK_EVT_MODE_RESUME: 108 return 0;
110 timer_ce_enabled = 1; 109}
111 break; 110
112 case CLOCK_EVT_MODE_SHUTDOWN: 111static int timer_ce_set_periodic(struct clock_event_device *evt)
113 timer_ce_enabled = 0; 112{
114 break; 113 timer_ce_enabled = 1;
115 default:
116 break;
117 }
118 smp_mb(); 114 smp_mb();
115 return 0;
119} 116}
120 117
121static __init void setup_timer_ce(void) 118static __init void setup_timer_ce(void)
@@ -127,7 +124,9 @@ static __init void setup_timer_ce(void)
127 ce->name = "timer_ce"; 124 ce->name = "timer_ce";
128 ce->rating = 100; 125 ce->rating = 100;
129 ce->features = CLOCK_EVT_FEAT_PERIODIC; 126 ce->features = CLOCK_EVT_FEAT_PERIODIC;
130 ce->set_mode = timer_ce_set_mode; 127 ce->set_state_shutdown = timer_ce_shutdown;
128 ce->set_state_periodic = timer_ce_set_periodic;
129 ce->tick_resume = timer_ce_set_periodic;
131 ce->cpumask = cpu_possible_mask; 130 ce->cpumask = cpu_possible_mask;
132 ce->shift = 32; 131 ce->shift = 32;
133 ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, 132 ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
@@ -183,24 +182,20 @@ static __init int setup_timer_cs(void)
183} 182}
184 183
185#ifdef CONFIG_SMP 184#ifdef CONFIG_SMP
186static void percpu_ce_setup(enum clock_event_mode mode, 185static int percpu_ce_shutdown(struct clock_event_device *evt)
187 struct clock_event_device *evt)
188{ 186{
189 int cpu = cpumask_first(evt->cpumask); 187 int cpu = cpumask_first(evt->cpumask);
190 188
191 switch (mode) { 189 sparc_config.load_profile_irq(cpu, 0);
192 case CLOCK_EVT_MODE_PERIODIC: 190 return 0;
193 sparc_config.load_profile_irq(cpu, 191}
194 SBUS_CLOCK_RATE / HZ); 192
195 break; 193static int percpu_ce_set_periodic(struct clock_event_device *evt)
196 case CLOCK_EVT_MODE_ONESHOT: 194{
197 case CLOCK_EVT_MODE_SHUTDOWN: 195 int cpu = cpumask_first(evt->cpumask);
198 case CLOCK_EVT_MODE_UNUSED: 196
199 sparc_config.load_profile_irq(cpu, 0); 197 sparc_config.load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
200 break; 198 return 0;
201 default:
202 break;
203 }
204} 199}
205 200
206static int percpu_ce_set_next_event(unsigned long delta, 201static int percpu_ce_set_next_event(unsigned long delta,
@@ -224,7 +219,9 @@ void register_percpu_ce(int cpu)
224 ce->name = "percpu_ce"; 219 ce->name = "percpu_ce";
225 ce->rating = 200; 220 ce->rating = 200;
226 ce->features = features; 221 ce->features = features;
227 ce->set_mode = percpu_ce_setup; 222 ce->set_state_shutdown = percpu_ce_shutdown;
223 ce->set_state_periodic = percpu_ce_set_periodic;
224 ce->set_state_oneshot = percpu_ce_shutdown;
228 ce->set_next_event = percpu_ce_set_next_event; 225 ce->set_next_event = percpu_ce_set_next_event;
229 ce->cpumask = cpumask_of(cpu); 226 ce->cpumask = cpumask_of(cpu);
230 ce->shift = 32; 227 ce->shift = 32;
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 2e6035c0a8ca..c69b21e51efc 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -674,32 +674,19 @@ static int sparc64_next_event(unsigned long delta,
674 return tick_ops->add_compare(delta) ? -ETIME : 0; 674 return tick_ops->add_compare(delta) ? -ETIME : 0;
675} 675}
676 676
677static void sparc64_timer_setup(enum clock_event_mode mode, 677static int sparc64_timer_shutdown(struct clock_event_device *evt)
678 struct clock_event_device *evt) 678{
679{ 679 tick_ops->disable_irq();
680 switch (mode) { 680 return 0;
681 case CLOCK_EVT_MODE_ONESHOT:
682 case CLOCK_EVT_MODE_RESUME:
683 break;
684
685 case CLOCK_EVT_MODE_SHUTDOWN:
686 tick_ops->disable_irq();
687 break;
688
689 case CLOCK_EVT_MODE_PERIODIC:
690 case CLOCK_EVT_MODE_UNUSED:
691 WARN_ON(1);
692 break;
693 }
694} 681}
695 682
696static struct clock_event_device sparc64_clockevent = { 683static struct clock_event_device sparc64_clockevent = {
697 .features = CLOCK_EVT_FEAT_ONESHOT, 684 .features = CLOCK_EVT_FEAT_ONESHOT,
698 .set_mode = sparc64_timer_setup, 685 .set_state_shutdown = sparc64_timer_shutdown,
699 .set_next_event = sparc64_next_event, 686 .set_next_event = sparc64_next_event,
700 .rating = 100, 687 .rating = 100,
701 .shift = 30, 688 .shift = 30,
702 .irq = -1, 689 .irq = -1,
703}; 690};
704static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); 691static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
705 692
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 117568d4f64a..5af441efb377 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -22,23 +22,16 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
22 local_irq_restore(flags); 22 local_irq_restore(flags);
23} 23}
24 24
25static void itimer_set_mode(enum clock_event_mode mode, 25static int itimer_shutdown(struct clock_event_device *evt)
26 struct clock_event_device *evt)
27{ 26{
28 switch (mode) { 27 disable_timer();
29 case CLOCK_EVT_MODE_PERIODIC: 28 return 0;
30 set_interval(); 29}
31 break; 30
32 31static int itimer_set_periodic(struct clock_event_device *evt)
33 case CLOCK_EVT_MODE_SHUTDOWN: 32{
34 case CLOCK_EVT_MODE_UNUSED: 33 set_interval();
35 case CLOCK_EVT_MODE_ONESHOT: 34 return 0;
36 disable_timer();
37 break;
38
39 case CLOCK_EVT_MODE_RESUME:
40 break;
41 }
42} 35}
43 36
44static int itimer_next_event(unsigned long delta, 37static int itimer_next_event(unsigned long delta,
@@ -48,14 +41,17 @@ static int itimer_next_event(unsigned long delta,
48} 41}
49 42
50static struct clock_event_device itimer_clockevent = { 43static struct clock_event_device itimer_clockevent = {
51 .name = "itimer", 44 .name = "itimer",
52 .rating = 250, 45 .rating = 250,
53 .cpumask = cpu_all_mask, 46 .cpumask = cpu_all_mask,
54 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 47 .features = CLOCK_EVT_FEAT_PERIODIC |
55 .set_mode = itimer_set_mode, 48 CLOCK_EVT_FEAT_ONESHOT,
56 .set_next_event = itimer_next_event, 49 .set_state_shutdown = itimer_shutdown,
57 .shift = 32, 50 .set_state_periodic = itimer_set_periodic,
58 .irq = 0, 51 .set_state_oneshot = itimer_shutdown,
52 .set_next_event = itimer_next_event,
53 .shift = 32,
54 .irq = 0,
59}; 55};
60 56
61static irqreturn_t um_timer(int irq, void *dev) 57static irqreturn_t um_timer(int irq, void *dev)
diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c
index d3824b2ff644..ac4c5449bb88 100644
--- a/arch/unicore32/kernel/time.c
+++ b/arch/unicore32/kernel/time.c
@@ -46,29 +46,20 @@ puv3_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
46 return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; 46 return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
47} 47}
48 48
49static void 49static int puv3_osmr0_shutdown(struct clock_event_device *evt)
50puv3_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
51{ 50{
52 switch (mode) { 51 writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
53 case CLOCK_EVT_MODE_ONESHOT: 52 writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
54 case CLOCK_EVT_MODE_UNUSED: 53 return 0;
55 case CLOCK_EVT_MODE_SHUTDOWN:
56 writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
57 writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
58 break;
59
60 case CLOCK_EVT_MODE_RESUME:
61 case CLOCK_EVT_MODE_PERIODIC:
62 break;
63 }
64} 54}
65 55
66static struct clock_event_device ckevt_puv3_osmr0 = { 56static struct clock_event_device ckevt_puv3_osmr0 = {
67 .name = "osmr0", 57 .name = "osmr0",
68 .features = CLOCK_EVT_FEAT_ONESHOT, 58 .features = CLOCK_EVT_FEAT_ONESHOT,
69 .rating = 200, 59 .rating = 200,
70 .set_next_event = puv3_osmr0_set_next_event, 60 .set_next_event = puv3_osmr0_set_next_event,
71 .set_mode = puv3_osmr0_set_mode, 61 .set_state_shutdown = puv3_osmr0_shutdown,
62 .set_state_oneshot = puv3_osmr0_shutdown,
72}; 63};
73 64
74static cycle_t puv3_read_oscr(struct clocksource *cs) 65static cycle_t puv3_read_oscr(struct clocksource *cs)
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/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 2a1823de69cc..b97767dbc7c8 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -52,8 +52,6 @@ static struct clocksource ccount_clocksource = {
52 52
53static int ccount_timer_set_next_event(unsigned long delta, 53static int ccount_timer_set_next_event(unsigned long delta,
54 struct clock_event_device *dev); 54 struct clock_event_device *dev);
55static void ccount_timer_set_mode(enum clock_event_mode mode,
56 struct clock_event_device *evt);
57struct ccount_timer { 55struct ccount_timer {
58 struct clock_event_device evt; 56 struct clock_event_device evt;
59 int irq_enabled; 57 int irq_enabled;
@@ -77,35 +75,34 @@ static int ccount_timer_set_next_event(unsigned long delta,
77 return ret; 75 return ret;
78} 76}
79 77
80static void ccount_timer_set_mode(enum clock_event_mode mode, 78/*
81 struct clock_event_device *evt) 79 * There is no way to disable the timer interrupt at the device level,
80 * only at the intenable register itself. Since enable_irq/disable_irq
81 * calls are nested, we need to make sure that these calls are
82 * balanced.
83 */
84static int ccount_timer_shutdown(struct clock_event_device *evt)
85{
86 struct ccount_timer *timer =
87 container_of(evt, struct ccount_timer, evt);
88
89 if (timer->irq_enabled) {
90 disable_irq(evt->irq);
91 timer->irq_enabled = 0;
92 }
93 return 0;
94}
95
96static int ccount_timer_set_oneshot(struct clock_event_device *evt)
82{ 97{
83 struct ccount_timer *timer = 98 struct ccount_timer *timer =
84 container_of(evt, struct ccount_timer, evt); 99 container_of(evt, struct ccount_timer, evt);
85 100
86 /* 101 if (!timer->irq_enabled) {
87 * There is no way to disable the timer interrupt at the device level, 102 enable_irq(evt->irq);
88 * only at the intenable register itself. Since enable_irq/disable_irq 103 timer->irq_enabled = 1;
89 * calls are nested, we need to make sure that these calls are
90 * balanced.
91 */
92 switch (mode) {
93 case CLOCK_EVT_MODE_SHUTDOWN:
94 case CLOCK_EVT_MODE_UNUSED:
95 if (timer->irq_enabled) {
96 disable_irq(evt->irq);
97 timer->irq_enabled = 0;
98 }
99 break;
100 case CLOCK_EVT_MODE_RESUME:
101 case CLOCK_EVT_MODE_ONESHOT:
102 if (!timer->irq_enabled) {
103 enable_irq(evt->irq);
104 timer->irq_enabled = 1;
105 }
106 default:
107 break;
108 } 104 }
105 return 0;
109} 106}
110 107
111static irqreturn_t timer_interrupt(int irq, void *dev_id); 108static irqreturn_t timer_interrupt(int irq, void *dev_id);
@@ -126,7 +123,9 @@ void local_timer_setup(unsigned cpu)
126 clockevent->features = CLOCK_EVT_FEAT_ONESHOT; 123 clockevent->features = CLOCK_EVT_FEAT_ONESHOT;
127 clockevent->rating = 300; 124 clockevent->rating = 300;
128 clockevent->set_next_event = ccount_timer_set_next_event; 125 clockevent->set_next_event = ccount_timer_set_next_event;
129 clockevent->set_mode = ccount_timer_set_mode; 126 clockevent->set_state_shutdown = ccount_timer_shutdown;
127 clockevent->set_state_oneshot = ccount_timer_set_oneshot;
128 clockevent->tick_resume = ccount_timer_set_oneshot;
130 clockevent->cpumask = cpumask_of(cpu); 129 clockevent->cpumask = cpumask_of(cpu);
131 clockevent->irq = irq_create_mapping(NULL, LINUX_TIMER_INT); 130 clockevent->irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
132 if (WARN(!clockevent->irq, "error: can't map timer irq")) 131 if (WARN(!clockevent->irq, "error: can't map timer irq"))
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4e57730e0be4..c03f04d82c6a 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -277,7 +277,7 @@ config CLKSRC_MIPS_GIC
277 277
278config CLKSRC_PXA 278config CLKSRC_PXA
279 def_bool y if ARCH_PXA || ARCH_SA1100 279 def_bool y if ARCH_PXA || ARCH_SA1100
280 select CLKSRC_OF if USE_OF 280 select CLKSRC_OF if OF
281 help 281 help
282 This enables OST0 support available on PXA and SA-11x0 282 This enables OST0 support available on PXA and SA-11x0
283 platforms. 283 platforms.
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 0aa135ddbf80..d6e3e49399dd 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -181,44 +181,36 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id)
181 return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt); 181 return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
182} 182}
183 183
184static __always_inline void timer_set_mode(const int access, int mode, 184static __always_inline int timer_shutdown(const int access,
185 struct clock_event_device *clk) 185 struct clock_event_device *clk)
186{ 186{
187 unsigned long ctrl; 187 unsigned long ctrl;
188 switch (mode) { 188
189 case CLOCK_EVT_MODE_UNUSED: 189 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
190 case CLOCK_EVT_MODE_SHUTDOWN: 190 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
191 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); 191 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
192 ctrl &= ~ARCH_TIMER_CTRL_ENABLE; 192
193 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); 193 return 0;
194 break;
195 default:
196 break;
197 }
198} 194}
199 195
200static void arch_timer_set_mode_virt(enum clock_event_mode mode, 196static int arch_timer_shutdown_virt(struct clock_event_device *clk)
201 struct clock_event_device *clk)
202{ 197{
203 timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode, clk); 198 return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
204} 199}
205 200
206static void arch_timer_set_mode_phys(enum clock_event_mode mode, 201static int arch_timer_shutdown_phys(struct clock_event_device *clk)
207 struct clock_event_device *clk)
208{ 202{
209 timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode, clk); 203 return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
210} 204}
211 205
212static void arch_timer_set_mode_virt_mem(enum clock_event_mode mode, 206static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk)
213 struct clock_event_device *clk)
214{ 207{
215 timer_set_mode(ARCH_TIMER_MEM_VIRT_ACCESS, mode, clk); 208 return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
216} 209}
217 210
218static void arch_timer_set_mode_phys_mem(enum clock_event_mode mode, 211static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk)
219 struct clock_event_device *clk)
220{ 212{
221 timer_set_mode(ARCH_TIMER_MEM_PHYS_ACCESS, mode, clk); 213 return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
222} 214}
223 215
224static __always_inline void set_next_event(const int access, unsigned long evt, 216static __always_inline void set_next_event(const int access, unsigned long evt,
@@ -273,11 +265,11 @@ static void __arch_timer_setup(unsigned type,
273 clk->cpumask = cpumask_of(smp_processor_id()); 265 clk->cpumask = cpumask_of(smp_processor_id());
274 if (arch_timer_use_virtual) { 266 if (arch_timer_use_virtual) {
275 clk->irq = arch_timer_ppi[VIRT_PPI]; 267 clk->irq = arch_timer_ppi[VIRT_PPI];
276 clk->set_mode = arch_timer_set_mode_virt; 268 clk->set_state_shutdown = arch_timer_shutdown_virt;
277 clk->set_next_event = arch_timer_set_next_event_virt; 269 clk->set_next_event = arch_timer_set_next_event_virt;
278 } else { 270 } else {
279 clk->irq = arch_timer_ppi[PHYS_SECURE_PPI]; 271 clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
280 clk->set_mode = arch_timer_set_mode_phys; 272 clk->set_state_shutdown = arch_timer_shutdown_phys;
281 clk->set_next_event = arch_timer_set_next_event_phys; 273 clk->set_next_event = arch_timer_set_next_event_phys;
282 } 274 }
283 } else { 275 } else {
@@ -286,17 +278,17 @@ static void __arch_timer_setup(unsigned type,
286 clk->rating = 400; 278 clk->rating = 400;
287 clk->cpumask = cpu_all_mask; 279 clk->cpumask = cpu_all_mask;
288 if (arch_timer_mem_use_virtual) { 280 if (arch_timer_mem_use_virtual) {
289 clk->set_mode = arch_timer_set_mode_virt_mem; 281 clk->set_state_shutdown = arch_timer_shutdown_virt_mem;
290 clk->set_next_event = 282 clk->set_next_event =
291 arch_timer_set_next_event_virt_mem; 283 arch_timer_set_next_event_virt_mem;
292 } else { 284 } else {
293 clk->set_mode = arch_timer_set_mode_phys_mem; 285 clk->set_state_shutdown = arch_timer_shutdown_phys_mem;
294 clk->set_next_event = 286 clk->set_next_event =
295 arch_timer_set_next_event_phys_mem; 287 arch_timer_set_next_event_phys_mem;
296 } 288 }
297 } 289 }
298 290
299 clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk); 291 clk->set_state_shutdown(clk);
300 292
301 clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); 293 clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
302} 294}
@@ -506,7 +498,7 @@ static void arch_timer_stop(struct clock_event_device *clk)
506 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]); 498 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
507 } 499 }
508 500
509 clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk); 501 clk->set_state_shutdown(clk);
510} 502}
511 503
512static int arch_timer_cpu_notify(struct notifier_block *self, 504static int arch_timer_cpu_notify(struct notifier_block *self,
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index e6833771a716..29ea50ac366a 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -107,26 +107,21 @@ static void gt_compare_set(unsigned long delta, int periodic)
107 writel(ctrl, gt_base + GT_CONTROL); 107 writel(ctrl, gt_base + GT_CONTROL);
108} 108}
109 109
110static void gt_clockevent_set_mode(enum clock_event_mode mode, 110static int gt_clockevent_shutdown(struct clock_event_device *evt)
111 struct clock_event_device *clk)
112{ 111{
113 unsigned long ctrl; 112 unsigned long ctrl;
114 113
115 switch (mode) { 114 ctrl = readl(gt_base + GT_CONTROL);
116 case CLOCK_EVT_MODE_PERIODIC: 115 ctrl &= ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE |
117 gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1); 116 GT_CONTROL_AUTO_INC);
118 break; 117 writel(ctrl, gt_base + GT_CONTROL);
119 case CLOCK_EVT_MODE_ONESHOT: 118 return 0;
120 case CLOCK_EVT_MODE_UNUSED: 119}
121 case CLOCK_EVT_MODE_SHUTDOWN: 120
122 ctrl = readl(gt_base + GT_CONTROL); 121static int gt_clockevent_set_periodic(struct clock_event_device *evt)
123 ctrl &= ~(GT_CONTROL_COMP_ENABLE | 122{
124 GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC); 123 gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
125 writel(ctrl, gt_base + GT_CONTROL); 124 return 0;
126 break;
127 default:
128 break;
129 }
130} 125}
131 126
132static int gt_clockevent_set_next_event(unsigned long evt, 127static int gt_clockevent_set_next_event(unsigned long evt,
@@ -155,7 +150,7 @@ static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
155 * the Global Timer flag _after_ having incremented 150 * the Global Timer flag _after_ having incremented
156 * the Comparator register value to a higher value. 151 * the Comparator register value to a higher value.
157 */ 152 */
158 if (evt->mode == CLOCK_EVT_MODE_ONESHOT) 153 if (clockevent_state_oneshot(evt))
159 gt_compare_set(ULONG_MAX, 0); 154 gt_compare_set(ULONG_MAX, 0);
160 155
161 writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS); 156 writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
@@ -171,7 +166,9 @@ static int gt_clockevents_init(struct clock_event_device *clk)
171 clk->name = "arm_global_timer"; 166 clk->name = "arm_global_timer";
172 clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 167 clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
173 CLOCK_EVT_FEAT_PERCPU; 168 CLOCK_EVT_FEAT_PERCPU;
174 clk->set_mode = gt_clockevent_set_mode; 169 clk->set_state_shutdown = gt_clockevent_shutdown;
170 clk->set_state_periodic = gt_clockevent_set_periodic;
171 clk->set_state_oneshot = gt_clockevent_shutdown;
175 clk->set_next_event = gt_clockevent_set_next_event; 172 clk->set_next_event = gt_clockevent_set_next_event;
176 clk->cpumask = cpumask_of(cpu); 173 clk->cpumask = cpumask_of(cpu);
177 clk->rating = 300; 174 clk->rating = 300;
@@ -184,7 +181,7 @@ static int gt_clockevents_init(struct clock_event_device *clk)
184 181
185static void gt_clockevents_stop(struct clock_event_device *clk) 182static void gt_clockevents_stop(struct clock_event_device *clk)
186{ 183{
187 gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk); 184 gt_clockevent_shutdown(clk);
188 disable_percpu_irq(clk->irq); 185 disable_percpu_irq(clk->irq);
189} 186}
190 187
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c
index 4c2ba59897e8..217438d39eb3 100644
--- a/drivers/clocksource/asm9260_timer.c
+++ b/drivers/clocksource/asm9260_timer.c
@@ -120,38 +120,52 @@ static int asm9260_timer_set_next_event(unsigned long delta,
120 return 0; 120 return 0;
121} 121}
122 122
123static void asm9260_timer_set_mode(enum clock_event_mode mode, 123static inline void __asm9260_timer_shutdown(struct clock_event_device *evt)
124 struct clock_event_device *evt)
125{ 124{
126 /* stop timer0 */ 125 /* stop timer0 */
127 writel_relaxed(BM_C0_EN, priv.base + HW_TCR + CLR_REG); 126 writel_relaxed(BM_C0_EN, priv.base + HW_TCR + CLR_REG);
127}
128
129static int asm9260_timer_shutdown(struct clock_event_device *evt)
130{
131 __asm9260_timer_shutdown(evt);
132 return 0;
133}
134
135static int asm9260_timer_set_oneshot(struct clock_event_device *evt)
136{
137 __asm9260_timer_shutdown(evt);
138
139 /* enable reset and stop on match */
140 writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
141 priv.base + HW_MCR + SET_REG);
142 return 0;
143}
144
145static int asm9260_timer_set_periodic(struct clock_event_device *evt)
146{
147 __asm9260_timer_shutdown(evt);
128 148
129 switch (mode) { 149 /* disable reset and stop on match */
130 case CLOCK_EVT_MODE_PERIODIC: 150 writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
131 /* disable reset and stop on match */ 151 priv.base + HW_MCR + CLR_REG);
132 writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0), 152 /* configure match count for TC0 */
133 priv.base + HW_MCR + CLR_REG); 153 writel_relaxed(priv.ticks_per_jiffy, priv.base + HW_MR0);
134 /* configure match count for TC0 */ 154 /* enable TC0 */
135 writel_relaxed(priv.ticks_per_jiffy, priv.base + HW_MR0); 155 writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG);
136 /* enable TC0 */ 156 return 0;
137 writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG);
138 break;
139 case CLOCK_EVT_MODE_ONESHOT:
140 /* enable reset and stop on match */
141 writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
142 priv.base + HW_MCR + SET_REG);
143 break;
144 default:
145 break;
146 }
147} 157}
148 158
149static struct clock_event_device event_dev = { 159static struct clock_event_device event_dev = {
150 .name = DRIVER_NAME, 160 .name = DRIVER_NAME,
151 .rating = 200, 161 .rating = 200,
152 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 162 .features = CLOCK_EVT_FEAT_PERIODIC |
153 .set_next_event = asm9260_timer_set_next_event, 163 CLOCK_EVT_FEAT_ONESHOT,
154 .set_mode = asm9260_timer_set_mode, 164 .set_next_event = asm9260_timer_set_next_event,
165 .set_state_shutdown = asm9260_timer_shutdown,
166 .set_state_periodic = asm9260_timer_set_periodic,
167 .set_state_oneshot = asm9260_timer_set_oneshot,
168 .tick_resume = asm9260_timer_shutdown,
155}; 169};
156 170
157static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id) 171static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id)
diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c
index 26ed331b1aad..6f2822928963 100644
--- a/drivers/clocksource/bcm2835_timer.c
+++ b/drivers/clocksource/bcm2835_timer.c
@@ -54,21 +54,6 @@ static u64 notrace bcm2835_sched_read(void)
54 return readl_relaxed(system_clock); 54 return readl_relaxed(system_clock);
55} 55}
56 56
57static void bcm2835_time_set_mode(enum clock_event_mode mode,
58 struct clock_event_device *evt_dev)
59{
60 switch (mode) {
61 case CLOCK_EVT_MODE_ONESHOT:
62 case CLOCK_EVT_MODE_UNUSED:
63 case CLOCK_EVT_MODE_SHUTDOWN:
64 case CLOCK_EVT_MODE_RESUME:
65 break;
66 default:
67 WARN(1, "%s: unhandled event mode %d\n", __func__, mode);
68 break;
69 }
70}
71
72static int bcm2835_time_set_next_event(unsigned long event, 57static int bcm2835_time_set_next_event(unsigned long event,
73 struct clock_event_device *evt_dev) 58 struct clock_event_device *evt_dev)
74{ 59{
@@ -129,7 +114,6 @@ static void __init bcm2835_timer_init(struct device_node *node)
129 timer->evt.name = node->name; 114 timer->evt.name = node->name;
130 timer->evt.rating = 300; 115 timer->evt.rating = 300;
131 timer->evt.features = CLOCK_EVT_FEAT_ONESHOT; 116 timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
132 timer->evt.set_mode = bcm2835_time_set_mode;
133 timer->evt.set_next_event = bcm2835_time_set_next_event; 117 timer->evt.set_next_event = bcm2835_time_set_next_event;
134 timer->evt.cpumask = cpumask_of(0); 118 timer->evt.cpumask = cpumask_of(0);
135 timer->act.name = node->name; 119 timer->act.name = node->name;
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c
index f1e33d08dd83..e717e87df9bc 100644
--- a/drivers/clocksource/bcm_kona_timer.c
+++ b/drivers/clocksource/bcm_kona_timer.c
@@ -127,25 +127,18 @@ static int kona_timer_set_next_event(unsigned long clc,
127 return 0; 127 return 0;
128} 128}
129 129
130static void kona_timer_set_mode(enum clock_event_mode mode, 130static int kona_timer_shutdown(struct clock_event_device *evt)
131 struct clock_event_device *unused)
132{ 131{
133 switch (mode) { 132 kona_timer_disable_and_clear(timers.tmr_regs);
134 case CLOCK_EVT_MODE_ONESHOT: 133 return 0;
135 /* by default mode is one shot don't do any thing */
136 break;
137 case CLOCK_EVT_MODE_UNUSED:
138 case CLOCK_EVT_MODE_SHUTDOWN:
139 default:
140 kona_timer_disable_and_clear(timers.tmr_regs);
141 }
142} 134}
143 135
144static struct clock_event_device kona_clockevent_timer = { 136static struct clock_event_device kona_clockevent_timer = {
145 .name = "timer 1", 137 .name = "timer 1",
146 .features = CLOCK_EVT_FEAT_ONESHOT, 138 .features = CLOCK_EVT_FEAT_ONESHOT,
147 .set_next_event = kona_timer_set_next_event, 139 .set_next_event = kona_timer_set_next_event,
148 .set_mode = kona_timer_set_mode 140 .set_state_shutdown = kona_timer_shutdown,
141 .tick_resume = kona_timer_shutdown,
149}; 142};
150 143
151static void __init kona_timer_clockevents_init(void) 144static void __init kona_timer_clockevents_init(void)
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
index 5ea91e3818d0..9be6018bd2b8 100644
--- a/drivers/clocksource/cadence_ttc_timer.c
+++ b/drivers/clocksource/cadence_ttc_timer.c
@@ -190,40 +190,42 @@ static int ttc_set_next_event(unsigned long cycles,
190} 190}
191 191
192/** 192/**
193 * ttc_set_mode - Sets the mode of timer 193 * ttc_set_{shutdown|oneshot|periodic} - Sets the state of timer
194 * 194 *
195 * @mode: Mode to be set
196 * @evt: Address of clock event instance 195 * @evt: Address of clock event instance
197 **/ 196 **/
198static void ttc_set_mode(enum clock_event_mode mode, 197static int ttc_shutdown(struct clock_event_device *evt)
199 struct clock_event_device *evt)
200{ 198{
201 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); 199 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
202 struct ttc_timer *timer = &ttce->ttc; 200 struct ttc_timer *timer = &ttce->ttc;
203 u32 ctrl_reg; 201 u32 ctrl_reg;
204 202
205 switch (mode) { 203 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
206 case CLOCK_EVT_MODE_PERIODIC: 204 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
207 ttc_set_interval(timer, DIV_ROUND_CLOSEST(ttce->ttc.freq, 205 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
208 PRESCALE * HZ)); 206 return 0;
209 break; 207}
210 case CLOCK_EVT_MODE_ONESHOT: 208
211 case CLOCK_EVT_MODE_UNUSED: 209static int ttc_set_periodic(struct clock_event_device *evt)
212 case CLOCK_EVT_MODE_SHUTDOWN: 210{
213 ctrl_reg = readl_relaxed(timer->base_addr + 211 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
214 TTC_CNT_CNTRL_OFFSET); 212 struct ttc_timer *timer = &ttce->ttc;
215 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; 213
216 writel_relaxed(ctrl_reg, 214 ttc_set_interval(timer,
217 timer->base_addr + TTC_CNT_CNTRL_OFFSET); 215 DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ));
218 break; 216 return 0;
219 case CLOCK_EVT_MODE_RESUME: 217}
220 ctrl_reg = readl_relaxed(timer->base_addr + 218
221 TTC_CNT_CNTRL_OFFSET); 219static int ttc_resume(struct clock_event_device *evt)
222 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; 220{
223 writel_relaxed(ctrl_reg, 221 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
224 timer->base_addr + TTC_CNT_CNTRL_OFFSET); 222 struct ttc_timer *timer = &ttce->ttc;
225 break; 223 u32 ctrl_reg;
226 } 224
225 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
226 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
227 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
228 return 0;
227} 229}
228 230
229static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, 231static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
@@ -429,7 +431,10 @@ static void __init ttc_setup_clockevent(struct clk *clk,
429 ttcce->ce.name = "ttc_clockevent"; 431 ttcce->ce.name = "ttc_clockevent";
430 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 432 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
431 ttcce->ce.set_next_event = ttc_set_next_event; 433 ttcce->ce.set_next_event = ttc_set_next_event;
432 ttcce->ce.set_mode = ttc_set_mode; 434 ttcce->ce.set_state_shutdown = ttc_shutdown;
435 ttcce->ce.set_state_periodic = ttc_set_periodic;
436 ttcce->ce.set_state_oneshot = ttc_shutdown;
437 ttcce->ce.tick_resume = ttc_resume;
433 ttcce->ce.rating = 200; 438 ttcce->ce.rating = 200;
434 ttcce->ce.irq = irq; 439 ttcce->ce.irq = irq;
435 ttcce->ce.cpumask = cpu_possible_mask; 440 ttcce->ce.cpumask = cpu_possible_mask;
diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c
index d83ec1f2fddc..cdd86e3525bb 100644
--- a/drivers/clocksource/clps711x-timer.c
+++ b/drivers/clocksource/clps711x-timer.c
@@ -61,11 +61,6 @@ static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id)
61 return IRQ_HANDLED; 61 return IRQ_HANDLED;
62} 62}
63 63
64static void clps711x_clockevent_set_mode(enum clock_event_mode mode,
65 struct clock_event_device *evt)
66{
67}
68
69static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base, 64static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base,
70 unsigned int irq) 65 unsigned int irq)
71{ 66{
@@ -91,7 +86,6 @@ static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base,
91 clkevt->name = "clps711x-clockevent"; 86 clkevt->name = "clps711x-clockevent";
92 clkevt->rating = 300; 87 clkevt->rating = 300;
93 clkevt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_C3STOP; 88 clkevt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_C3STOP;
94 clkevt->set_mode = clps711x_clockevent_set_mode;
95 clkevt->cpumask = cpumask_of(0); 89 clkevt->cpumask = cpumask_of(0);
96 clockevents_config_and_register(clkevt, HZ, 0, 0); 90 clockevents_config_and_register(clkevt, HZ, 0, 0);
97 91
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c
index db2105290898..9a7e37cf56b0 100644
--- a/drivers/clocksource/cs5535-clockevt.c
+++ b/drivers/clocksource/cs5535-clockevt.c
@@ -42,7 +42,6 @@ MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks.");
42 * 256 128 .125 512.000 42 * 256 128 .125 512.000
43 */ 43 */
44 44
45static unsigned int cs5535_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
46static struct cs5535_mfgpt_timer *cs5535_event_clock; 45static struct cs5535_mfgpt_timer *cs5535_event_clock;
47 46
48/* Selected from the table above */ 47/* Selected from the table above */
@@ -77,15 +76,17 @@ static void start_timer(struct cs5535_mfgpt_timer *timer, uint16_t delta)
77 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); 76 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
78} 77}
79 78
80static void mfgpt_set_mode(enum clock_event_mode mode, 79static int mfgpt_shutdown(struct clock_event_device *evt)
81 struct clock_event_device *evt)
82{ 80{
83 disable_timer(cs5535_event_clock); 81 disable_timer(cs5535_event_clock);
82 return 0;
83}
84 84
85 if (mode == CLOCK_EVT_MODE_PERIODIC) 85static int mfgpt_set_periodic(struct clock_event_device *evt)
86 start_timer(cs5535_event_clock, MFGPT_PERIODIC); 86{
87 87 disable_timer(cs5535_event_clock);
88 cs5535_tick_mode = mode; 88 start_timer(cs5535_event_clock, MFGPT_PERIODIC);
89 return 0;
89} 90}
90 91
91static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) 92static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
@@ -97,7 +98,10 @@ static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
97static struct clock_event_device cs5535_clockevent = { 98static struct clock_event_device cs5535_clockevent = {
98 .name = DRV_NAME, 99 .name = DRV_NAME,
99 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 100 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
100 .set_mode = mfgpt_set_mode, 101 .set_state_shutdown = mfgpt_shutdown,
102 .set_state_periodic = mfgpt_set_periodic,
103 .set_state_oneshot = mfgpt_shutdown,
104 .tick_resume = mfgpt_shutdown,
101 .set_next_event = mfgpt_next_event, 105 .set_next_event = mfgpt_next_event,
102 .rating = 250, 106 .rating = 250,
103}; 107};
@@ -113,7 +117,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
113 /* Turn off the clock (and clear the event) */ 117 /* Turn off the clock (and clear the event) */
114 disable_timer(cs5535_event_clock); 118 disable_timer(cs5535_event_clock);
115 119
116 if (cs5535_tick_mode == CLOCK_EVT_MODE_SHUTDOWN) 120 if (clockevent_state_shutdown(&cs5535_clockevent))
117 return IRQ_HANDLED; 121 return IRQ_HANDLED;
118 122
119 /* Clear the counter */ 123 /* Clear the counter */
@@ -121,7 +125,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
121 125
122 /* Restart the clock in periodic mode */ 126 /* Restart the clock in periodic mode */
123 127
124 if (cs5535_tick_mode == CLOCK_EVT_MODE_PERIODIC) 128 if (clockevent_state_periodic(&cs5535_clockevent))
125 cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP, 129 cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP,
126 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); 130 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
127 131
diff --git a/drivers/clocksource/dummy_timer.c b/drivers/clocksource/dummy_timer.c
index 31990600fcff..776b6c86dcd5 100644
--- a/drivers/clocksource/dummy_timer.c
+++ b/drivers/clocksource/dummy_timer.c
@@ -16,15 +16,6 @@
16 16
17static DEFINE_PER_CPU(struct clock_event_device, dummy_timer_evt); 17static DEFINE_PER_CPU(struct clock_event_device, dummy_timer_evt);
18 18
19static void dummy_timer_set_mode(enum clock_event_mode mode,
20 struct clock_event_device *evt)
21{
22 /*
23 * Core clockevents code will call this when exchanging timer devices.
24 * We don't need to do anything here.
25 */
26}
27
28static void dummy_timer_setup(void) 19static void dummy_timer_setup(void)
29{ 20{
30 int cpu = smp_processor_id(); 21 int cpu = smp_processor_id();
@@ -35,7 +26,6 @@ static void dummy_timer_setup(void)
35 CLOCK_EVT_FEAT_ONESHOT | 26 CLOCK_EVT_FEAT_ONESHOT |
36 CLOCK_EVT_FEAT_DUMMY; 27 CLOCK_EVT_FEAT_DUMMY;
37 evt->rating = 100; 28 evt->rating = 100;
38 evt->set_mode = dummy_timer_set_mode;
39 evt->cpumask = cpumask_of(cpu); 29 evt->cpumask = cpumask_of(cpu);
40 30
41 clockevents_register_device(evt); 31 clockevents_register_device(evt);
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
index 35a88097af3c..c76c75006ea6 100644
--- a/drivers/clocksource/dw_apb_timer.c
+++ b/drivers/clocksource/dw_apb_timer.c
@@ -110,71 +110,87 @@ static void apbt_enable_int(struct dw_apb_timer *timer)
110 apbt_writel(timer, ctrl, APBTMR_N_CONTROL); 110 apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
111} 111}
112 112
113static void apbt_set_mode(enum clock_event_mode mode, 113static int apbt_shutdown(struct clock_event_device *evt)
114 struct clock_event_device *evt)
115{ 114{
115 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
116 unsigned long ctrl; 116 unsigned long ctrl;
117 unsigned long period; 117
118 pr_debug("%s CPU %d state=shutdown\n", __func__,
119 cpumask_first(evt->cpumask));
120
121 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
122 ctrl &= ~APBTMR_CONTROL_ENABLE;
123 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
124 return 0;
125}
126
127static int apbt_set_oneshot(struct clock_event_device *evt)
128{
118 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 129 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
130 unsigned long ctrl;
119 131
120 pr_debug("%s CPU %d mode=%d\n", __func__, 132 pr_debug("%s CPU %d state=oneshot\n", __func__,
121 cpumask_first(evt->cpumask), 133 cpumask_first(evt->cpumask));
122 mode); 134
123 135 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
124 switch (mode) { 136 /*
125 case CLOCK_EVT_MODE_PERIODIC: 137 * set free running mode, this mode will let timer reload max
126 period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); 138 * timeout which will give time (3min on 25MHz clock) to rearm
127 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 139 * the next event, therefore emulate the one-shot mode.
128 ctrl |= APBTMR_CONTROL_MODE_PERIODIC; 140 */
129 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 141 ctrl &= ~APBTMR_CONTROL_ENABLE;
130 /* 142 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
131 * DW APB p. 46, have to disable timer before load counter, 143
132 * may cause sync problem. 144 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
133 */ 145 /* write again to set free running mode */
134 ctrl &= ~APBTMR_CONTROL_ENABLE; 146 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
135 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 147
136 udelay(1); 148 /*
137 pr_debug("Setting clock period %lu for HZ %d\n", period, HZ); 149 * DW APB p. 46, load counter with all 1s before starting free
138 apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT); 150 * running mode.
139 ctrl |= APBTMR_CONTROL_ENABLE; 151 */
140 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 152 apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT);
141 break; 153 ctrl &= ~APBTMR_CONTROL_INT;
142 154 ctrl |= APBTMR_CONTROL_ENABLE;
143 case CLOCK_EVT_MODE_ONESHOT: 155 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
144 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 156 return 0;
145 /* 157}
146 * set free running mode, this mode will let timer reload max 158
147 * timeout which will give time (3min on 25MHz clock) to rearm 159static int apbt_set_periodic(struct clock_event_device *evt)
148 * the next event, therefore emulate the one-shot mode. 160{
149 */ 161 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
150 ctrl &= ~APBTMR_CONTROL_ENABLE; 162 unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ);
151 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; 163 unsigned long ctrl;
152 164
153 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 165 pr_debug("%s CPU %d state=periodic\n", __func__,
154 /* write again to set free running mode */ 166 cpumask_first(evt->cpumask));
155 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 167
156 168 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
157 /* 169 ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
158 * DW APB p. 46, load counter with all 1s before starting free 170 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
159 * running mode. 171 /*
160 */ 172 * DW APB p. 46, have to disable timer before load counter,
161 apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT); 173 * may cause sync problem.
162 ctrl &= ~APBTMR_CONTROL_INT; 174 */
163 ctrl |= APBTMR_CONTROL_ENABLE; 175 ctrl &= ~APBTMR_CONTROL_ENABLE;
164 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 176 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
165 break; 177 udelay(1);
166 178 pr_debug("Setting clock period %lu for HZ %d\n", period, HZ);
167 case CLOCK_EVT_MODE_UNUSED: 179 apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT);
168 case CLOCK_EVT_MODE_SHUTDOWN: 180 ctrl |= APBTMR_CONTROL_ENABLE;
169 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 181 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
170 ctrl &= ~APBTMR_CONTROL_ENABLE; 182 return 0;
171 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 183}
172 break; 184
173 185static int apbt_resume(struct clock_event_device *evt)
174 case CLOCK_EVT_MODE_RESUME: 186{
175 apbt_enable_int(&dw_ced->timer); 187 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
176 break; 188
177 } 189 pr_debug("%s CPU %d state=resume\n", __func__,
190 cpumask_first(evt->cpumask));
191
192 apbt_enable_int(&dw_ced->timer);
193 return 0;
178} 194}
179 195
180static int apbt_next_event(unsigned long delta, 196static int apbt_next_event(unsigned long delta,
@@ -232,8 +248,12 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
232 &dw_ced->ced); 248 &dw_ced->ced);
233 dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); 249 dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced);
234 dw_ced->ced.cpumask = cpumask_of(cpu); 250 dw_ced->ced.cpumask = cpumask_of(cpu);
235 dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 251 dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC |
236 dw_ced->ced.set_mode = apbt_set_mode; 252 CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
253 dw_ced->ced.set_state_shutdown = apbt_shutdown;
254 dw_ced->ced.set_state_periodic = apbt_set_periodic;
255 dw_ced->ced.set_state_oneshot = apbt_set_oneshot;
256 dw_ced->ced.tick_resume = apbt_resume;
237 dw_ced->ced.set_next_event = apbt_next_event; 257 dw_ced->ced.set_next_event = apbt_next_event;
238 dw_ced->ced.irq = dw_ced->timer.irq; 258 dw_ced->ced.irq = dw_ced->timer.irq;
239 dw_ced->ced.rating = rating; 259 dw_ced->ced.rating = rating;
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index dc3c6ee04aaa..7a97a34dba70 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -251,33 +251,21 @@ static struct em_sti_priv *ced_to_em_sti(struct clock_event_device *ced)
251 return container_of(ced, struct em_sti_priv, ced); 251 return container_of(ced, struct em_sti_priv, ced);
252} 252}
253 253
254static void em_sti_clock_event_mode(enum clock_event_mode mode, 254static int em_sti_clock_event_shutdown(struct clock_event_device *ced)
255 struct clock_event_device *ced)
256{ 255{
257 struct em_sti_priv *p = ced_to_em_sti(ced); 256 struct em_sti_priv *p = ced_to_em_sti(ced);
257 em_sti_stop(p, USER_CLOCKEVENT);
258 return 0;
259}
258 260
259 /* deal with old setting first */ 261static int em_sti_clock_event_set_oneshot(struct clock_event_device *ced)
260 switch (ced->mode) { 262{
261 case CLOCK_EVT_MODE_ONESHOT: 263 struct em_sti_priv *p = ced_to_em_sti(ced);
262 em_sti_stop(p, USER_CLOCKEVENT);
263 break;
264 default:
265 break;
266 }
267 264
268 switch (mode) { 265 dev_info(&p->pdev->dev, "used for oneshot clock events\n");
269 case CLOCK_EVT_MODE_ONESHOT: 266 em_sti_start(p, USER_CLOCKEVENT);
270 dev_info(&p->pdev->dev, "used for oneshot clock events\n"); 267 clockevents_config(&p->ced, p->rate);
271 em_sti_start(p, USER_CLOCKEVENT); 268 return 0;
272 clockevents_config(&p->ced, p->rate);
273 break;
274 case CLOCK_EVT_MODE_SHUTDOWN:
275 case CLOCK_EVT_MODE_UNUSED:
276 em_sti_stop(p, USER_CLOCKEVENT);
277 break;
278 default:
279 break;
280 }
281} 269}
282 270
283static int em_sti_clock_event_next(unsigned long delta, 271static int em_sti_clock_event_next(unsigned long delta,
@@ -303,11 +291,12 @@ static void em_sti_register_clockevent(struct em_sti_priv *p)
303 ced->rating = 200; 291 ced->rating = 200;
304 ced->cpumask = cpu_possible_mask; 292 ced->cpumask = cpu_possible_mask;
305 ced->set_next_event = em_sti_clock_event_next; 293 ced->set_next_event = em_sti_clock_event_next;
306 ced->set_mode = em_sti_clock_event_mode; 294 ced->set_state_shutdown = em_sti_clock_event_shutdown;
295 ced->set_state_oneshot = em_sti_clock_event_set_oneshot;
307 296
308 dev_info(&p->pdev->dev, "used for clock events\n"); 297 dev_info(&p->pdev->dev, "used for clock events\n");
309 298
310 /* Register with dummy 1 Hz value, gets updated in ->set_mode() */ 299 /* Register with dummy 1 Hz value, gets updated in ->set_state_oneshot() */
311 clockevents_config_and_register(ced, 1, 2, 0xffffffff); 300 clockevents_config_and_register(ced, 1, 2, 0xffffffff);
312} 301}
313 302
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 9064ff743598..029f96ab131a 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -257,15 +257,14 @@ static void exynos4_mct_comp0_stop(void)
257 exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); 257 exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
258} 258}
259 259
260static void exynos4_mct_comp0_start(enum clock_event_mode mode, 260static void exynos4_mct_comp0_start(bool periodic, unsigned long cycles)
261 unsigned long cycles)
262{ 261{
263 unsigned int tcon; 262 unsigned int tcon;
264 cycle_t comp_cycle; 263 cycle_t comp_cycle;
265 264
266 tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); 265 tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
267 266
268 if (mode == CLOCK_EVT_MODE_PERIODIC) { 267 if (periodic) {
269 tcon |= MCT_G_TCON_COMP0_AUTO_INC; 268 tcon |= MCT_G_TCON_COMP0_AUTO_INC;
270 exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); 269 exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
271 } 270 }
@@ -283,38 +282,38 @@ static void exynos4_mct_comp0_start(enum clock_event_mode mode,
283static int exynos4_comp_set_next_event(unsigned long cycles, 282static int exynos4_comp_set_next_event(unsigned long cycles,
284 struct clock_event_device *evt) 283 struct clock_event_device *evt)
285{ 284{
286 exynos4_mct_comp0_start(evt->mode, cycles); 285 exynos4_mct_comp0_start(false, cycles);
287 286
288 return 0; 287 return 0;
289} 288}
290 289
291static void exynos4_comp_set_mode(enum clock_event_mode mode, 290static int mct_set_state_shutdown(struct clock_event_device *evt)
292 struct clock_event_device *evt)
293{ 291{
294 unsigned long cycles_per_jiffy;
295 exynos4_mct_comp0_stop(); 292 exynos4_mct_comp0_stop();
293 return 0;
294}
296 295
297 switch (mode) { 296static int mct_set_state_periodic(struct clock_event_device *evt)
298 case CLOCK_EVT_MODE_PERIODIC: 297{
299 cycles_per_jiffy = 298 unsigned long cycles_per_jiffy;
300 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
301 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
302 break;
303 299
304 case CLOCK_EVT_MODE_ONESHOT: 300 cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
305 case CLOCK_EVT_MODE_UNUSED: 301 >> evt->shift);
306 case CLOCK_EVT_MODE_SHUTDOWN: 302 exynos4_mct_comp0_stop();
307 case CLOCK_EVT_MODE_RESUME: 303 exynos4_mct_comp0_start(true, cycles_per_jiffy);
308 break; 304 return 0;
309 }
310} 305}
311 306
312static struct clock_event_device mct_comp_device = { 307static struct clock_event_device mct_comp_device = {
313 .name = "mct-comp", 308 .name = "mct-comp",
314 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 309 .features = CLOCK_EVT_FEAT_PERIODIC |
315 .rating = 250, 310 CLOCK_EVT_FEAT_ONESHOT,
316 .set_next_event = exynos4_comp_set_next_event, 311 .rating = 250,
317 .set_mode = exynos4_comp_set_mode, 312 .set_next_event = exynos4_comp_set_next_event,
313 .set_state_periodic = mct_set_state_periodic,
314 .set_state_shutdown = mct_set_state_shutdown,
315 .set_state_oneshot = mct_set_state_shutdown,
316 .tick_resume = mct_set_state_shutdown,
318}; 317};
319 318
320static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) 319static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
@@ -390,39 +389,32 @@ static int exynos4_tick_set_next_event(unsigned long cycles,
390 return 0; 389 return 0;
391} 390}
392 391
393static inline void exynos4_tick_set_mode(enum clock_event_mode mode, 392static int set_state_shutdown(struct clock_event_device *evt)
394 struct clock_event_device *evt) 393{
394 exynos4_mct_tick_stop(this_cpu_ptr(&percpu_mct_tick));
395 return 0;
396}
397
398static int set_state_periodic(struct clock_event_device *evt)
395{ 399{
396 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 400 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
397 unsigned long cycles_per_jiffy; 401 unsigned long cycles_per_jiffy;
398 402
403 cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
404 >> evt->shift);
399 exynos4_mct_tick_stop(mevt); 405 exynos4_mct_tick_stop(mevt);
400 406 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
401 switch (mode) { 407 return 0;
402 case CLOCK_EVT_MODE_PERIODIC:
403 cycles_per_jiffy =
404 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
405 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
406 break;
407
408 case CLOCK_EVT_MODE_ONESHOT:
409 case CLOCK_EVT_MODE_UNUSED:
410 case CLOCK_EVT_MODE_SHUTDOWN:
411 case CLOCK_EVT_MODE_RESUME:
412 break;
413 }
414} 408}
415 409
416static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) 410static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
417{ 411{
418 struct clock_event_device *evt = &mevt->evt;
419
420 /* 412 /*
421 * This is for supporting oneshot mode. 413 * This is for supporting oneshot mode.
422 * Mct would generate interrupt periodically 414 * Mct would generate interrupt periodically
423 * without explicit stopping. 415 * without explicit stopping.
424 */ 416 */
425 if (evt->mode != CLOCK_EVT_MODE_PERIODIC) 417 if (!clockevent_state_periodic(&mevt->evt))
426 exynos4_mct_tick_stop(mevt); 418 exynos4_mct_tick_stop(mevt);
427 419
428 /* Clear the MCT tick interrupt */ 420 /* Clear the MCT tick interrupt */
@@ -442,20 +434,21 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
442 return IRQ_HANDLED; 434 return IRQ_HANDLED;
443} 435}
444 436
445static int exynos4_local_timer_setup(struct clock_event_device *evt) 437static int exynos4_local_timer_setup(struct mct_clock_event_device *mevt)
446{ 438{
447 struct mct_clock_event_device *mevt; 439 struct clock_event_device *evt = &mevt->evt;
448 unsigned int cpu = smp_processor_id(); 440 unsigned int cpu = smp_processor_id();
449 441
450 mevt = container_of(evt, struct mct_clock_event_device, evt);
451
452 mevt->base = EXYNOS4_MCT_L_BASE(cpu); 442 mevt->base = EXYNOS4_MCT_L_BASE(cpu);
453 snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu); 443 snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);
454 444
455 evt->name = mevt->name; 445 evt->name = mevt->name;
456 evt->cpumask = cpumask_of(cpu); 446 evt->cpumask = cpumask_of(cpu);
457 evt->set_next_event = exynos4_tick_set_next_event; 447 evt->set_next_event = exynos4_tick_set_next_event;
458 evt->set_mode = exynos4_tick_set_mode; 448 evt->set_state_periodic = set_state_periodic;
449 evt->set_state_shutdown = set_state_shutdown;
450 evt->set_state_oneshot = set_state_shutdown;
451 evt->tick_resume = set_state_shutdown;
459 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 452 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
460 evt->rating = 450; 453 evt->rating = 450;
461 454
@@ -477,9 +470,11 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
477 return 0; 470 return 0;
478} 471}
479 472
480static void exynos4_local_timer_stop(struct clock_event_device *evt) 473static void exynos4_local_timer_stop(struct mct_clock_event_device *mevt)
481{ 474{
482 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 475 struct clock_event_device *evt = &mevt->evt;
476
477 evt->set_state_shutdown(evt);
483 if (mct_int_type == MCT_INT_SPI) { 478 if (mct_int_type == MCT_INT_SPI) {
484 if (evt->irq != -1) 479 if (evt->irq != -1)
485 disable_irq_nosync(evt->irq); 480 disable_irq_nosync(evt->irq);
@@ -500,11 +495,11 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self,
500 switch (action & ~CPU_TASKS_FROZEN) { 495 switch (action & ~CPU_TASKS_FROZEN) {
501 case CPU_STARTING: 496 case CPU_STARTING:
502 mevt = this_cpu_ptr(&percpu_mct_tick); 497 mevt = this_cpu_ptr(&percpu_mct_tick);
503 exynos4_local_timer_setup(&mevt->evt); 498 exynos4_local_timer_setup(mevt);
504 break; 499 break;
505 case CPU_DYING: 500 case CPU_DYING:
506 mevt = this_cpu_ptr(&percpu_mct_tick); 501 mevt = this_cpu_ptr(&percpu_mct_tick);
507 exynos4_local_timer_stop(&mevt->evt); 502 exynos4_local_timer_stop(mevt);
508 break; 503 break;
509 } 504 }
510 505
@@ -570,7 +565,7 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
570 goto out_irq; 565 goto out_irq;
571 566
572 /* Immediately configure the timer on the boot CPU */ 567 /* Immediately configure the timer on the boot CPU */
573 exynos4_local_timer_setup(&mevt->evt); 568 exynos4_local_timer_setup(mevt);
574 return; 569 return;
575 570
576out_irq: 571out_irq:
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
index 454227d4f895..ef434699c80a 100644
--- a/drivers/clocksource/fsl_ftm_timer.c
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -153,19 +153,16 @@ static int ftm_set_next_event(unsigned long delta,
153 return 0; 153 return 0;
154} 154}
155 155
156static void ftm_set_mode(enum clock_event_mode mode, 156static int ftm_set_oneshot(struct clock_event_device *evt)
157 struct clock_event_device *evt)
158{ 157{
159 switch (mode) { 158 ftm_counter_disable(priv->clkevt_base);
160 case CLOCK_EVT_MODE_PERIODIC: 159 return 0;
161 ftm_set_next_event(priv->periodic_cyc, evt); 160}
162 break; 161
163 case CLOCK_EVT_MODE_ONESHOT: 162static int ftm_set_periodic(struct clock_event_device *evt)
164 ftm_counter_disable(priv->clkevt_base); 163{
165 break; 164 ftm_set_next_event(priv->periodic_cyc, evt);
166 default: 165 return 0;
167 return;
168 }
169} 166}
170 167
171static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id) 168static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id)
@@ -174,7 +171,7 @@ static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id)
174 171
175 ftm_irq_acknowledge(priv->clkevt_base); 172 ftm_irq_acknowledge(priv->clkevt_base);
176 173
177 if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT)) { 174 if (likely(clockevent_state_oneshot(evt))) {
178 ftm_irq_disable(priv->clkevt_base); 175 ftm_irq_disable(priv->clkevt_base);
179 ftm_counter_disable(priv->clkevt_base); 176 ftm_counter_disable(priv->clkevt_base);
180 } 177 }
@@ -185,11 +182,13 @@ static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id)
185} 182}
186 183
187static struct clock_event_device ftm_clockevent = { 184static struct clock_event_device ftm_clockevent = {
188 .name = "Freescale ftm timer", 185 .name = "Freescale ftm timer",
189 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 186 .features = CLOCK_EVT_FEAT_PERIODIC |
190 .set_mode = ftm_set_mode, 187 CLOCK_EVT_FEAT_ONESHOT,
191 .set_next_event = ftm_set_next_event, 188 .set_state_periodic = ftm_set_periodic,
192 .rating = 300, 189 .set_state_oneshot = ftm_set_oneshot,
190 .set_next_event = ftm_set_next_event,
191 .rating = 300,
193}; 192};
194 193
195static struct irqaction ftm_timer_irq = { 194static struct irqaction ftm_timer_irq = {
diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c
index 0214cb3a7f5e..f9b3b7033a97 100644
--- a/drivers/clocksource/h8300_timer8.c
+++ b/drivers/clocksource/h8300_timer8.c
@@ -81,7 +81,7 @@ static irqreturn_t timer8_interrupt(int irq, void *dev_id)
81 p->flags |= FLAG_IRQCONTEXT; 81 p->flags |= FLAG_IRQCONTEXT;
82 ctrl_outw(p->tcora, p->mapbase + TCORA); 82 ctrl_outw(p->tcora, p->mapbase + TCORA);
83 if (!(p->flags & FLAG_SKIPEVENT)) { 83 if (!(p->flags & FLAG_SKIPEVENT)) {
84 if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) 84 if (clockevent_state_oneshot(&p->ced))
85 ctrl_outw(0x0000, p->mapbase + _8TCR); 85 ctrl_outw(0x0000, p->mapbase + _8TCR);
86 p->ced.event_handler(&p->ced); 86 p->ced.event_handler(&p->ced);
87 } 87 }
@@ -169,29 +169,32 @@ static void timer8_clock_event_start(struct timer8_priv *p, int periodic)
169 timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000); 169 timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000);
170} 170}
171 171
172static void timer8_clock_event_mode(enum clock_event_mode mode, 172static int timer8_clock_event_shutdown(struct clock_event_device *ced)
173 struct clock_event_device *ced) 173{
174 timer8_stop(ced_to_priv(ced));
175 return 0;
176}
177
178static int timer8_clock_event_periodic(struct clock_event_device *ced)
174{ 179{
175 struct timer8_priv *p = ced_to_priv(ced); 180 struct timer8_priv *p = ced_to_priv(ced);
176 181
177 switch (mode) { 182 dev_info(&p->pdev->dev, "used for periodic clock events\n");
178 case CLOCK_EVT_MODE_PERIODIC: 183 timer8_stop(p);
179 dev_info(&p->pdev->dev, "used for periodic clock events\n"); 184 timer8_clock_event_start(p, PERIODIC);
180 timer8_stop(p); 185
181 timer8_clock_event_start(p, PERIODIC); 186 return 0;
182 break; 187}
183 case CLOCK_EVT_MODE_ONESHOT: 188
184 dev_info(&p->pdev->dev, "used for oneshot clock events\n"); 189static int timer8_clock_event_oneshot(struct clock_event_device *ced)
185 timer8_stop(p); 190{
186 timer8_clock_event_start(p, ONESHOT); 191 struct timer8_priv *p = ced_to_priv(ced);
187 break; 192
188 case CLOCK_EVT_MODE_SHUTDOWN: 193 dev_info(&p->pdev->dev, "used for oneshot clock events\n");
189 case CLOCK_EVT_MODE_UNUSED: 194 timer8_stop(p);
190 timer8_stop(p); 195 timer8_clock_event_start(p, ONESHOT);
191 break; 196
192 default: 197 return 0;
193 break;
194 }
195} 198}
196 199
197static int timer8_clock_event_next(unsigned long delta, 200static int timer8_clock_event_next(unsigned long delta,
@@ -199,7 +202,7 @@ static int timer8_clock_event_next(unsigned long delta,
199{ 202{
200 struct timer8_priv *p = ced_to_priv(ced); 203 struct timer8_priv *p = ced_to_priv(ced);
201 204
202 BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); 205 BUG_ON(!clockevent_state_oneshot(ced));
203 timer8_set_next(p, delta - 1); 206 timer8_set_next(p, delta - 1);
204 207
205 return 0; 208 return 0;
@@ -246,7 +249,9 @@ static int timer8_setup(struct timer8_priv *p,
246 p->ced.rating = 200; 249 p->ced.rating = 200;
247 p->ced.cpumask = cpumask_of(0); 250 p->ced.cpumask = cpumask_of(0);
248 p->ced.set_next_event = timer8_clock_event_next; 251 p->ced.set_next_event = timer8_clock_event_next;
249 p->ced.set_mode = timer8_clock_event_mode; 252 p->ced.set_state_shutdown = timer8_clock_event_shutdown;
253 p->ced.set_state_periodic = timer8_clock_event_periodic;
254 p->ced.set_state_oneshot = timer8_clock_event_oneshot;
250 255
251 ret = setup_irq(irq, &p->irqaction); 256 ret = setup_irq(irq, &p->irqaction);
252 if (ret < 0) { 257 if (ret < 0) {
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.
diff --git a/drivers/clocksource/meson6_timer.c b/drivers/clocksource/meson6_timer.c
index 5c15cba41dca..1fa22c4d2d49 100644
--- a/drivers/clocksource/meson6_timer.c
+++ b/drivers/clocksource/meson6_timer.c
@@ -67,25 +67,25 @@ static void meson6_clkevt_time_start(unsigned char timer, bool periodic)
67 writel(val | TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX); 67 writel(val | TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
68} 68}
69 69
70static void meson6_clkevt_mode(enum clock_event_mode mode, 70static int meson6_shutdown(struct clock_event_device *evt)
71 struct clock_event_device *clk)
72{ 71{
73 switch (mode) { 72 meson6_clkevt_time_stop(CED_ID);
74 case CLOCK_EVT_MODE_PERIODIC: 73 return 0;
75 meson6_clkevt_time_stop(CED_ID); 74}
76 meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC/HZ - 1); 75
77 meson6_clkevt_time_start(CED_ID, true); 76static int meson6_set_oneshot(struct clock_event_device *evt)
78 break; 77{
79 case CLOCK_EVT_MODE_ONESHOT: 78 meson6_clkevt_time_stop(CED_ID);
80 meson6_clkevt_time_stop(CED_ID); 79 meson6_clkevt_time_start(CED_ID, false);
81 meson6_clkevt_time_start(CED_ID, false); 80 return 0;
82 break; 81}
83 case CLOCK_EVT_MODE_UNUSED: 82
84 case CLOCK_EVT_MODE_SHUTDOWN: 83static int meson6_set_periodic(struct clock_event_device *evt)
85 default: 84{
86 meson6_clkevt_time_stop(CED_ID); 85 meson6_clkevt_time_stop(CED_ID);
87 break; 86 meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC / HZ - 1);
88 } 87 meson6_clkevt_time_start(CED_ID, true);
88 return 0;
89} 89}
90 90
91static int meson6_clkevt_next_event(unsigned long evt, 91static int meson6_clkevt_next_event(unsigned long evt,
@@ -99,11 +99,15 @@ static int meson6_clkevt_next_event(unsigned long evt,
99} 99}
100 100
101static struct clock_event_device meson6_clockevent = { 101static struct clock_event_device meson6_clockevent = {
102 .name = "meson6_tick", 102 .name = "meson6_tick",
103 .rating = 400, 103 .rating = 400,
104 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 104 .features = CLOCK_EVT_FEAT_PERIODIC |
105 .set_mode = meson6_clkevt_mode, 105 CLOCK_EVT_FEAT_ONESHOT,
106 .set_next_event = meson6_clkevt_next_event, 106 .set_state_shutdown = meson6_shutdown,
107 .set_state_periodic = meson6_set_periodic,
108 .set_state_oneshot = meson6_set_oneshot,
109 .tick_resume = meson6_shutdown,
110 .set_next_event = meson6_clkevt_next_event,
107}; 111};
108 112
109static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id) 113static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id)
diff --git a/drivers/clocksource/metag_generic.c b/drivers/clocksource/metag_generic.c
index b7384b853e5a..bcd5c0d602a0 100644
--- a/drivers/clocksource/metag_generic.c
+++ b/drivers/clocksource/metag_generic.c
@@ -56,25 +56,6 @@ static int metag_timer_set_next_event(unsigned long delta,
56 return 0; 56 return 0;
57} 57}
58 58
59static void metag_timer_set_mode(enum clock_event_mode mode,
60 struct clock_event_device *evt)
61{
62 switch (mode) {
63 case CLOCK_EVT_MODE_ONESHOT:
64 case CLOCK_EVT_MODE_RESUME:
65 break;
66
67 case CLOCK_EVT_MODE_SHUTDOWN:
68 /* We should disable the IRQ here */
69 break;
70
71 case CLOCK_EVT_MODE_PERIODIC:
72 case CLOCK_EVT_MODE_UNUSED:
73 WARN_ON(1);
74 break;
75 };
76}
77
78static cycle_t metag_clocksource_read(struct clocksource *cs) 59static cycle_t metag_clocksource_read(struct clocksource *cs)
79{ 60{
80 return __core_reg_get(TXTIMER); 61 return __core_reg_get(TXTIMER);
@@ -129,7 +110,6 @@ static void arch_timer_setup(unsigned int cpu)
129 clk->rating = 200, 110 clk->rating = 200,
130 clk->shift = 12, 111 clk->shift = 12,
131 clk->irq = tbisig_map(TBID_SIGNUM_TRT), 112 clk->irq = tbisig_map(TBID_SIGNUM_TRT),
132 clk->set_mode = metag_timer_set_mode,
133 clk->set_next_event = metag_timer_set_next_event, 113 clk->set_next_event = metag_timer_set_next_event,
134 114
135 clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift); 115 clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift);
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index b81ed1a5342d..c3810b61c815 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -33,12 +33,6 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
33 return res; 33 return res;
34} 34}
35 35
36static void gic_set_clock_mode(enum clock_event_mode mode,
37 struct clock_event_device *evt)
38{
39 /* Nothing to do ... */
40}
41
42static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) 36static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
43{ 37{
44 struct clock_event_device *cd = dev_id; 38 struct clock_event_device *cd = dev_id;
@@ -67,7 +61,6 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd)
67 cd->irq = gic_timer_irq; 61 cd->irq = gic_timer_irq;
68 cd->cpumask = cpumask_of(cpu); 62 cd->cpumask = cpumask_of(cpu);
69 cd->set_next_event = gic_next_event; 63 cd->set_next_event = gic_next_event;
70 cd->set_mode = gic_set_clock_mode;
71 64
72 clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff); 65 clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff);
73 66
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c
index 5eb2c35932b1..19857af651c1 100644
--- a/drivers/clocksource/moxart_timer.c
+++ b/drivers/clocksource/moxart_timer.c
@@ -58,25 +58,24 @@
58static void __iomem *base; 58static void __iomem *base;
59static unsigned int clock_count_per_tick; 59static unsigned int clock_count_per_tick;
60 60
61static void moxart_clkevt_mode(enum clock_event_mode mode, 61static int moxart_shutdown(struct clock_event_device *evt)
62 struct clock_event_device *clk)
63{ 62{
64 switch (mode) { 63 writel(TIMER1_DISABLE, base + TIMER_CR);
65 case CLOCK_EVT_MODE_RESUME: 64 return 0;
66 case CLOCK_EVT_MODE_ONESHOT: 65}
67 writel(TIMER1_DISABLE, base + TIMER_CR); 66
68 writel(~0, base + TIMER1_BASE + REG_LOAD); 67static int moxart_set_oneshot(struct clock_event_device *evt)
69 break; 68{
70 case CLOCK_EVT_MODE_PERIODIC: 69 writel(TIMER1_DISABLE, base + TIMER_CR);
71 writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD); 70 writel(~0, base + TIMER1_BASE + REG_LOAD);
72 writel(TIMER1_ENABLE, base + TIMER_CR); 71 return 0;
73 break; 72}
74 case CLOCK_EVT_MODE_UNUSED: 73
75 case CLOCK_EVT_MODE_SHUTDOWN: 74static int moxart_set_periodic(struct clock_event_device *evt)
76 default: 75{
77 writel(TIMER1_DISABLE, base + TIMER_CR); 76 writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD);
78 break; 77 writel(TIMER1_ENABLE, base + TIMER_CR);
79 } 78 return 0;
80} 79}
81 80
82static int moxart_clkevt_next_event(unsigned long cycles, 81static int moxart_clkevt_next_event(unsigned long cycles,
@@ -95,11 +94,15 @@ static int moxart_clkevt_next_event(unsigned long cycles,
95} 94}
96 95
97static struct clock_event_device moxart_clockevent = { 96static struct clock_event_device moxart_clockevent = {
98 .name = "moxart_timer", 97 .name = "moxart_timer",
99 .rating = 200, 98 .rating = 200,
100 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 99 .features = CLOCK_EVT_FEAT_PERIODIC |
101 .set_mode = moxart_clkevt_mode, 100 CLOCK_EVT_FEAT_ONESHOT,
102 .set_next_event = moxart_clkevt_next_event, 101 .set_state_shutdown = moxart_shutdown,
102 .set_state_periodic = moxart_set_periodic,
103 .set_state_oneshot = moxart_set_oneshot,
104 .tick_resume = moxart_set_oneshot,
105 .set_next_event = moxart_clkevt_next_event,
103}; 106};
104 107
105static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id) 108static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 68ab42356d0e..50f0641c65b6 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -102,27 +102,20 @@ static void mtk_clkevt_time_start(struct mtk_clock_event_device *evt,
102 evt->gpt_base + TIMER_CTRL_REG(timer)); 102 evt->gpt_base + TIMER_CTRL_REG(timer));
103} 103}
104 104
105static void mtk_clkevt_mode(enum clock_event_mode mode, 105static int mtk_clkevt_shutdown(struct clock_event_device *clk)
106 struct clock_event_device *clk) 106{
107 mtk_clkevt_time_stop(to_mtk_clk(clk), GPT_CLK_EVT);
108 return 0;
109}
110
111static int mtk_clkevt_set_periodic(struct clock_event_device *clk)
107{ 112{
108 struct mtk_clock_event_device *evt = to_mtk_clk(clk); 113 struct mtk_clock_event_device *evt = to_mtk_clk(clk);
109 114
110 mtk_clkevt_time_stop(evt, GPT_CLK_EVT); 115 mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
111 116 mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
112 switch (mode) { 117 mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
113 case CLOCK_EVT_MODE_PERIODIC: 118 return 0;
114 mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
115 mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
116 break;
117 case CLOCK_EVT_MODE_ONESHOT:
118 /* Timer is enabled in set_next_event */
119 break;
120 case CLOCK_EVT_MODE_UNUSED:
121 case CLOCK_EVT_MODE_SHUTDOWN:
122 default:
123 /* No more interrupts will occur as source is disabled */
124 break;
125 }
126} 119}
127 120
128static int mtk_clkevt_next_event(unsigned long event, 121static int mtk_clkevt_next_event(unsigned long event,
@@ -196,7 +189,10 @@ static void __init mtk_timer_init(struct device_node *node)
196 evt->dev.name = "mtk_tick"; 189 evt->dev.name = "mtk_tick";
197 evt->dev.rating = 300; 190 evt->dev.rating = 300;
198 evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 191 evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
199 evt->dev.set_mode = mtk_clkevt_mode; 192 evt->dev.set_state_shutdown = mtk_clkevt_shutdown;
193 evt->dev.set_state_periodic = mtk_clkevt_set_periodic;
194 evt->dev.set_state_oneshot = mtk_clkevt_shutdown;
195 evt->dev.tick_resume = mtk_clkevt_shutdown;
200 evt->dev.set_next_event = mtk_clkevt_next_event; 196 evt->dev.set_next_event = mtk_clkevt_next_event;
201 evt->dev.cpumask = cpu_possible_mask; 197 evt->dev.cpumask = cpu_possible_mask;
202 198
diff --git a/drivers/clocksource/mxs_timer.c b/drivers/clocksource/mxs_timer.c
index 445b68a01dc5..f5ce2961c0d6 100644
--- a/drivers/clocksource/mxs_timer.c
+++ b/drivers/clocksource/mxs_timer.c
@@ -77,7 +77,6 @@
77#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf 77#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf
78 78
79static struct clock_event_device mxs_clockevent_device; 79static struct clock_event_device mxs_clockevent_device;
80static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
81 80
82static void __iomem *mxs_timrot_base; 81static void __iomem *mxs_timrot_base;
83static u32 timrot_major_version; 82static u32 timrot_major_version;
@@ -141,64 +140,49 @@ static struct irqaction mxs_timer_irq = {
141 .handler = mxs_timer_interrupt, 140 .handler = mxs_timer_interrupt,
142}; 141};
143 142
144#ifdef DEBUG 143static void mxs_irq_clear(char *state)
145static const char *clock_event_mode_label[] const = {
146 [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
147 [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
148 [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
149 [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
150};
151#endif /* DEBUG */
152
153static void mxs_set_mode(enum clock_event_mode mode,
154 struct clock_event_device *evt)
155{ 144{
156 /* Disable interrupt in timer module */ 145 /* Disable interrupt in timer module */
157 timrot_irq_disable(); 146 timrot_irq_disable();
158 147
159 if (mode != mxs_clockevent_mode) { 148 /* Set event time into the furthest future */
160 /* Set event time into the furthest future */ 149 if (timrot_is_v1())
161 if (timrot_is_v1()) 150 __raw_writel(0xffff, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
162 __raw_writel(0xffff, 151 else
163 mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1)); 152 __raw_writel(0xffffffff,
164 else 153 mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
165 __raw_writel(0xffffffff, 154
166 mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1)); 155 /* Clear pending interrupt */
167 156 timrot_irq_acknowledge();
168 /* Clear pending interrupt */
169 timrot_irq_acknowledge();
170 }
171 157
172#ifdef DEBUG 158#ifdef DEBUG
173 pr_info("%s: changing mode from %s to %s\n", __func__, 159 pr_info("%s: changing mode to %s\n", __func__, state)
174 clock_event_mode_label[mxs_clockevent_mode],
175 clock_event_mode_label[mode]);
176#endif /* DEBUG */ 160#endif /* DEBUG */
161}
177 162
178 /* Remember timer mode */ 163static int mxs_shutdown(struct clock_event_device *evt)
179 mxs_clockevent_mode = mode; 164{
180 165 mxs_irq_clear("shutdown");
181 switch (mode) { 166
182 case CLOCK_EVT_MODE_PERIODIC: 167 return 0;
183 pr_err("%s: Periodic mode is not implemented\n", __func__); 168}
184 break; 169
185 case CLOCK_EVT_MODE_ONESHOT: 170static int mxs_set_oneshot(struct clock_event_device *evt)
186 timrot_irq_enable(); 171{
187 break; 172 if (clockevent_state_oneshot(evt))
188 case CLOCK_EVT_MODE_SHUTDOWN: 173 mxs_irq_clear("oneshot");
189 case CLOCK_EVT_MODE_UNUSED: 174 timrot_irq_enable();
190 case CLOCK_EVT_MODE_RESUME: 175 return 0;
191 /* Left event sources disabled, no more interrupts appear */
192 break;
193 }
194} 176}
195 177
196static struct clock_event_device mxs_clockevent_device = { 178static struct clock_event_device mxs_clockevent_device = {
197 .name = "mxs_timrot", 179 .name = "mxs_timrot",
198 .features = CLOCK_EVT_FEAT_ONESHOT, 180 .features = CLOCK_EVT_FEAT_ONESHOT,
199 .set_mode = mxs_set_mode, 181 .set_state_shutdown = mxs_shutdown,
200 .set_next_event = timrotv2_set_next_event, 182 .set_state_oneshot = mxs_set_oneshot,
201 .rating = 200, 183 .tick_resume = mxs_shutdown,
184 .set_next_event = timrotv2_set_next_event,
185 .rating = 200,
202}; 186};
203 187
204static int __init mxs_clockevent_init(struct clk *timer_clk) 188static int __init mxs_clockevent_init(struct clk *timer_clk)
diff --git a/drivers/clocksource/nomadik-mtu.c b/drivers/clocksource/nomadik-mtu.c
index a709cfa49d85..bc8dd443c727 100644
--- a/drivers/clocksource/nomadik-mtu.c
+++ b/drivers/clocksource/nomadik-mtu.c
@@ -119,28 +119,27 @@ static void nmdk_clkevt_reset(void)
119 } 119 }
120} 120}
121 121
122static void nmdk_clkevt_mode(enum clock_event_mode mode, 122static int nmdk_clkevt_shutdown(struct clock_event_device *evt)
123 struct clock_event_device *dev)
124{ 123{
125 switch (mode) { 124 writel(0, mtu_base + MTU_IMSC);
126 case CLOCK_EVT_MODE_PERIODIC: 125 /* disable timer */
127 clkevt_periodic = true; 126 writel(0, mtu_base + MTU_CR(1));
128 nmdk_clkevt_reset(); 127 /* load some high default value */
129 break; 128 writel(0xffffffff, mtu_base + MTU_LR(1));
130 case CLOCK_EVT_MODE_ONESHOT: 129 return 0;
131 clkevt_periodic = false; 130}
132 break; 131
133 case CLOCK_EVT_MODE_SHUTDOWN: 132static int nmdk_clkevt_set_oneshot(struct clock_event_device *evt)
134 case CLOCK_EVT_MODE_UNUSED: 133{
135 writel(0, mtu_base + MTU_IMSC); 134 clkevt_periodic = false;
136 /* disable timer */ 135 return 0;
137 writel(0, mtu_base + MTU_CR(1)); 136}
138 /* load some high default value */ 137
139 writel(0xffffffff, mtu_base + MTU_LR(1)); 138static int nmdk_clkevt_set_periodic(struct clock_event_device *evt)
140 break; 139{
141 case CLOCK_EVT_MODE_RESUME: 140 clkevt_periodic = true;
142 break; 141 nmdk_clkevt_reset();
143 } 142 return 0;
144} 143}
145 144
146static void nmdk_clksrc_reset(void) 145static void nmdk_clksrc_reset(void)
@@ -163,13 +162,16 @@ static void nmdk_clkevt_resume(struct clock_event_device *cedev)
163} 162}
164 163
165static struct clock_event_device nmdk_clkevt = { 164static struct clock_event_device nmdk_clkevt = {
166 .name = "mtu_1", 165 .name = "mtu_1",
167 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC | 166 .features = CLOCK_EVT_FEAT_ONESHOT |
168 CLOCK_EVT_FEAT_DYNIRQ, 167 CLOCK_EVT_FEAT_PERIODIC |
169 .rating = 200, 168 CLOCK_EVT_FEAT_DYNIRQ,
170 .set_mode = nmdk_clkevt_mode, 169 .rating = 200,
171 .set_next_event = nmdk_clkevt_next, 170 .set_state_shutdown = nmdk_clkevt_shutdown,
172 .resume = nmdk_clkevt_resume, 171 .set_state_periodic = nmdk_clkevt_set_periodic,
172 .set_state_oneshot = nmdk_clkevt_set_oneshot,
173 .set_next_event = nmdk_clkevt_next,
174 .resume = nmdk_clkevt_resume,
173}; 175};
174 176
175/* 177/*
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/pxa_timer.c
index d9438af2bbd6..45b6a4999713 100644
--- a/drivers/clocksource/pxa_timer.c
+++ b/drivers/clocksource/pxa_timer.c
@@ -88,26 +88,12 @@ pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
88 return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; 88 return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
89} 89}
90 90
91static void 91static int pxa_osmr0_shutdown(struct clock_event_device *evt)
92pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
93{ 92{
94 switch (mode) { 93 /* initializing, released, or preparing for suspend */
95 case CLOCK_EVT_MODE_ONESHOT: 94 timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
96 timer_writel(timer_readl(OIER) & ~OIER_E0, OIER); 95 timer_writel(OSSR_M0, OSSR);
97 timer_writel(OSSR_M0, OSSR); 96 return 0;
98 break;
99
100 case CLOCK_EVT_MODE_UNUSED:
101 case CLOCK_EVT_MODE_SHUTDOWN:
102 /* initializing, released, or preparing for suspend */
103 timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
104 timer_writel(OSSR_M0, OSSR);
105 break;
106
107 case CLOCK_EVT_MODE_RESUME:
108 case CLOCK_EVT_MODE_PERIODIC:
109 break;
110 }
111} 97}
112 98
113#ifdef CONFIG_PM 99#ifdef CONFIG_PM
@@ -147,13 +133,14 @@ static void pxa_timer_resume(struct clock_event_device *cedev)
147#endif 133#endif
148 134
149static struct clock_event_device ckevt_pxa_osmr0 = { 135static struct clock_event_device ckevt_pxa_osmr0 = {
150 .name = "osmr0", 136 .name = "osmr0",
151 .features = CLOCK_EVT_FEAT_ONESHOT, 137 .features = CLOCK_EVT_FEAT_ONESHOT,
152 .rating = 200, 138 .rating = 200,
153 .set_next_event = pxa_osmr0_set_next_event, 139 .set_next_event = pxa_osmr0_set_next_event,
154 .set_mode = pxa_osmr0_set_mode, 140 .set_state_shutdown = pxa_osmr0_shutdown,
155 .suspend = pxa_timer_suspend, 141 .set_state_oneshot = pxa_osmr0_shutdown,
156 .resume = pxa_timer_resume, 142 .suspend = pxa_timer_suspend,
143 .resume = pxa_timer_resume,
157}; 144};
158 145
159static struct irqaction pxa_ost0_irq = { 146static struct irqaction pxa_ost0_irq = {
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
index cba2d015564c..f8e09f923651 100644
--- a/drivers/clocksource/qcom-timer.c
+++ b/drivers/clocksource/qcom-timer.c
@@ -47,7 +47,7 @@ static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
47{ 47{
48 struct clock_event_device *evt = dev_id; 48 struct clock_event_device *evt = dev_id;
49 /* Stop the timer tick */ 49 /* Stop the timer tick */
50 if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { 50 if (clockevent_state_oneshot(evt)) {
51 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); 51 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
52 ctrl &= ~TIMER_ENABLE_EN; 52 ctrl &= ~TIMER_ENABLE_EN;
53 writel_relaxed(ctrl, event_base + TIMER_ENABLE); 53 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
@@ -75,26 +75,14 @@ static int msm_timer_set_next_event(unsigned long cycles,
75 return 0; 75 return 0;
76} 76}
77 77
78static void msm_timer_set_mode(enum clock_event_mode mode, 78static int msm_timer_shutdown(struct clock_event_device *evt)
79 struct clock_event_device *evt)
80{ 79{
81 u32 ctrl; 80 u32 ctrl;
82 81
83 ctrl = readl_relaxed(event_base + TIMER_ENABLE); 82 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
84 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); 83 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
85
86 switch (mode) {
87 case CLOCK_EVT_MODE_RESUME:
88 case CLOCK_EVT_MODE_PERIODIC:
89 break;
90 case CLOCK_EVT_MODE_ONESHOT:
91 /* Timer is enabled in set_next_event */
92 break;
93 case CLOCK_EVT_MODE_UNUSED:
94 case CLOCK_EVT_MODE_SHUTDOWN:
95 break;
96 }
97 writel_relaxed(ctrl, event_base + TIMER_ENABLE); 84 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
85 return 0;
98} 86}
99 87
100static struct clock_event_device __percpu *msm_evt; 88static struct clock_event_device __percpu *msm_evt;
@@ -126,7 +114,9 @@ static int msm_local_timer_setup(struct clock_event_device *evt)
126 evt->name = "msm_timer"; 114 evt->name = "msm_timer";
127 evt->features = CLOCK_EVT_FEAT_ONESHOT; 115 evt->features = CLOCK_EVT_FEAT_ONESHOT;
128 evt->rating = 200; 116 evt->rating = 200;
129 evt->set_mode = msm_timer_set_mode; 117 evt->set_state_shutdown = msm_timer_shutdown;
118 evt->set_state_oneshot = msm_timer_shutdown;
119 evt->tick_resume = msm_timer_shutdown;
130 evt->set_next_event = msm_timer_set_next_event; 120 evt->set_next_event = msm_timer_set_next_event;
131 evt->cpumask = cpumask_of(cpu); 121 evt->cpumask = cpumask_of(cpu);
132 122
@@ -147,7 +137,7 @@ static int msm_local_timer_setup(struct clock_event_device *evt)
147 137
148static void msm_local_timer_stop(struct clock_event_device *evt) 138static void msm_local_timer_stop(struct clock_event_device *evt)
149{ 139{
150 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 140 evt->set_state_shutdown(evt);
151 disable_percpu_irq(evt->irq); 141 disable_percpu_irq(evt->irq);
152} 142}
153 143
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index a35993bafb20..bb2c2b050964 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -82,23 +82,18 @@ static inline int rk_timer_set_next_event(unsigned long cycles,
82 return 0; 82 return 0;
83} 83}
84 84
85static inline void rk_timer_set_mode(enum clock_event_mode mode, 85static int rk_timer_shutdown(struct clock_event_device *ce)
86 struct clock_event_device *ce)
87{ 86{
88 switch (mode) { 87 rk_timer_disable(ce);
89 case CLOCK_EVT_MODE_PERIODIC: 88 return 0;
90 rk_timer_disable(ce); 89}
91 rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); 90
92 rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING); 91static int rk_timer_set_periodic(struct clock_event_device *ce)
93 break; 92{
94 case CLOCK_EVT_MODE_ONESHOT: 93 rk_timer_disable(ce);
95 case CLOCK_EVT_MODE_RESUME: 94 rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
96 break; 95 rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING);
97 case CLOCK_EVT_MODE_UNUSED: 96 return 0;
98 case CLOCK_EVT_MODE_SHUTDOWN:
99 rk_timer_disable(ce);
100 break;
101 }
102} 97}
103 98
104static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) 99static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
@@ -107,7 +102,7 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
107 102
108 rk_timer_interrupt_clear(ce); 103 rk_timer_interrupt_clear(ce);
109 104
110 if (ce->mode == CLOCK_EVT_MODE_ONESHOT) 105 if (clockevent_state_oneshot(ce))
111 rk_timer_disable(ce); 106 rk_timer_disable(ce);
112 107
113 ce->event_handler(ce); 108 ce->event_handler(ce);
@@ -161,7 +156,8 @@ static void __init rk_timer_init(struct device_node *np)
161 ce->name = TIMER_NAME; 156 ce->name = TIMER_NAME;
162 ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 157 ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
163 ce->set_next_event = rk_timer_set_next_event; 158 ce->set_next_event = rk_timer_set_next_event;
164 ce->set_mode = rk_timer_set_mode; 159 ce->set_state_shutdown = rk_timer_shutdown;
160 ce->set_state_periodic = rk_timer_set_periodic;
165 ce->irq = irq; 161 ce->irq = irq;
166 ce->cpumask = cpumask_of(0); 162 ce->cpumask = cpumask_of(0);
167 ce->rating = 250; 163 ce->rating = 250;
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 5645cfc90c41..bc90e13338cc 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -207,25 +207,18 @@ static int samsung_set_next_event(unsigned long cycles,
207 return 0; 207 return 0;
208} 208}
209 209
210static void samsung_set_mode(enum clock_event_mode mode, 210static int samsung_shutdown(struct clock_event_device *evt)
211 struct clock_event_device *evt)
212{ 211{
213 samsung_time_stop(pwm.event_id); 212 samsung_time_stop(pwm.event_id);
213 return 0;
214}
214 215
215 switch (mode) { 216static int samsung_set_periodic(struct clock_event_device *evt)
216 case CLOCK_EVT_MODE_PERIODIC: 217{
217 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1); 218 samsung_time_stop(pwm.event_id);
218 samsung_time_start(pwm.event_id, true); 219 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
219 break; 220 samsung_time_start(pwm.event_id, true);
220 221 return 0;
221 case CLOCK_EVT_MODE_ONESHOT:
222 break;
223
224 case CLOCK_EVT_MODE_UNUSED:
225 case CLOCK_EVT_MODE_SHUTDOWN:
226 case CLOCK_EVT_MODE_RESUME:
227 break;
228 }
229} 222}
230 223
231static void samsung_clockevent_resume(struct clock_event_device *cev) 224static void samsung_clockevent_resume(struct clock_event_device *cev)
@@ -240,12 +233,16 @@ static void samsung_clockevent_resume(struct clock_event_device *cev)
240} 233}
241 234
242static struct clock_event_device time_event_device = { 235static struct clock_event_device time_event_device = {
243 .name = "samsung_event_timer", 236 .name = "samsung_event_timer",
244 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 237 .features = CLOCK_EVT_FEAT_PERIODIC |
245 .rating = 200, 238 CLOCK_EVT_FEAT_ONESHOT,
246 .set_next_event = samsung_set_next_event, 239 .rating = 200,
247 .set_mode = samsung_set_mode, 240 .set_next_event = samsung_set_next_event,
248 .resume = samsung_clockevent_resume, 241 .set_state_shutdown = samsung_shutdown,
242 .set_state_periodic = samsung_set_periodic,
243 .set_state_oneshot = samsung_shutdown,
244 .tick_resume = samsung_shutdown,
245 .resume = samsung_clockevent_resume,
249}; 246};
250 247
251static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) 248static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index c96de14036a0..ba73a6eb8d66 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -538,7 +538,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
538 538
539 if (ch->flags & FLAG_CLOCKEVENT) { 539 if (ch->flags & FLAG_CLOCKEVENT) {
540 if (!(ch->flags & FLAG_SKIPEVENT)) { 540 if (!(ch->flags & FLAG_SKIPEVENT)) {
541 if (ch->ced.mode == CLOCK_EVT_MODE_ONESHOT) { 541 if (clockevent_state_oneshot(&ch->ced)) {
542 ch->next_match_value = ch->max_match_value; 542 ch->next_match_value = ch->max_match_value;
543 ch->flags |= FLAG_REPROGRAM; 543 ch->flags |= FLAG_REPROGRAM;
544 } 544 }
@@ -554,7 +554,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
554 sh_cmt_clock_event_program_verify(ch, 1); 554 sh_cmt_clock_event_program_verify(ch, 1);
555 555
556 if (ch->flags & FLAG_CLOCKEVENT) 556 if (ch->flags & FLAG_CLOCKEVENT)
557 if ((ch->ced.mode == CLOCK_EVT_MODE_SHUTDOWN) 557 if ((clockevent_state_shutdown(&ch->ced))
558 || (ch->match_value == ch->next_match_value)) 558 || (ch->match_value == ch->next_match_value))
559 ch->flags &= ~FLAG_REPROGRAM; 559 ch->flags &= ~FLAG_REPROGRAM;
560 } 560 }
@@ -726,39 +726,37 @@ static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
726 sh_cmt_set_next(ch, ch->max_match_value); 726 sh_cmt_set_next(ch, ch->max_match_value);
727} 727}
728 728
729static void sh_cmt_clock_event_mode(enum clock_event_mode mode, 729static int sh_cmt_clock_event_shutdown(struct clock_event_device *ced)
730 struct clock_event_device *ced) 730{
731 struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
732
733 sh_cmt_stop(ch, FLAG_CLOCKEVENT);
734 return 0;
735}
736
737static int sh_cmt_clock_event_set_state(struct clock_event_device *ced,
738 int periodic)
731{ 739{
732 struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); 740 struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
733 741
734 /* deal with old setting first */ 742 /* deal with old setting first */
735 switch (ced->mode) { 743 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
736 case CLOCK_EVT_MODE_PERIODIC:
737 case CLOCK_EVT_MODE_ONESHOT:
738 sh_cmt_stop(ch, FLAG_CLOCKEVENT); 744 sh_cmt_stop(ch, FLAG_CLOCKEVENT);
739 break;
740 default:
741 break;
742 }
743 745
744 switch (mode) { 746 dev_info(&ch->cmt->pdev->dev, "ch%u: used for %s clock events\n",
745 case CLOCK_EVT_MODE_PERIODIC: 747 ch->index, periodic ? "periodic" : "oneshot");
746 dev_info(&ch->cmt->pdev->dev, 748 sh_cmt_clock_event_start(ch, periodic);
747 "ch%u: used for periodic clock events\n", ch->index); 749 return 0;
748 sh_cmt_clock_event_start(ch, 1); 750}
749 break; 751
750 case CLOCK_EVT_MODE_ONESHOT: 752static int sh_cmt_clock_event_set_oneshot(struct clock_event_device *ced)
751 dev_info(&ch->cmt->pdev->dev, 753{
752 "ch%u: used for oneshot clock events\n", ch->index); 754 return sh_cmt_clock_event_set_state(ced, 0);
753 sh_cmt_clock_event_start(ch, 0); 755}
754 break; 756
755 case CLOCK_EVT_MODE_SHUTDOWN: 757static int sh_cmt_clock_event_set_periodic(struct clock_event_device *ced)
756 case CLOCK_EVT_MODE_UNUSED: 758{
757 sh_cmt_stop(ch, FLAG_CLOCKEVENT); 759 return sh_cmt_clock_event_set_state(ced, 1);
758 break;
759 default:
760 break;
761 }
762} 760}
763 761
764static int sh_cmt_clock_event_next(unsigned long delta, 762static int sh_cmt_clock_event_next(unsigned long delta,
@@ -766,7 +764,7 @@ static int sh_cmt_clock_event_next(unsigned long delta,
766{ 764{
767 struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); 765 struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
768 766
769 BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); 767 BUG_ON(!clockevent_state_oneshot(ced));
770 if (likely(ch->flags & FLAG_IRQCONTEXT)) 768 if (likely(ch->flags & FLAG_IRQCONTEXT))
771 ch->next_match_value = delta - 1; 769 ch->next_match_value = delta - 1;
772 else 770 else
@@ -820,7 +818,9 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
820 ced->rating = 125; 818 ced->rating = 125;
821 ced->cpumask = cpu_possible_mask; 819 ced->cpumask = cpu_possible_mask;
822 ced->set_next_event = sh_cmt_clock_event_next; 820 ced->set_next_event = sh_cmt_clock_event_next;
823 ced->set_mode = sh_cmt_clock_event_mode; 821 ced->set_state_shutdown = sh_cmt_clock_event_shutdown;
822 ced->set_state_periodic = sh_cmt_clock_event_set_periodic;
823 ced->set_state_oneshot = sh_cmt_clock_event_set_oneshot;
824 ced->suspend = sh_cmt_clock_event_suspend; 824 ced->suspend = sh_cmt_clock_event_suspend;
825 ced->resume = sh_cmt_clock_event_resume; 825 ced->resume = sh_cmt_clock_event_resume;
826 826
@@ -935,9 +935,6 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
935static const struct platform_device_id sh_cmt_id_table[] = { 935static const struct platform_device_id sh_cmt_id_table[] = {
936 { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] }, 936 { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
937 { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] }, 937 { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
938 { "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
939 { "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
940 { "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
941 { } 938 { }
942}; 939};
943MODULE_DEVICE_TABLE(platform, sh_cmt_id_table); 940MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 3d88698cf2b8..f1985da8113f 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -276,36 +276,25 @@ static struct sh_mtu2_channel *ced_to_sh_mtu2(struct clock_event_device *ced)
276 return container_of(ced, struct sh_mtu2_channel, ced); 276 return container_of(ced, struct sh_mtu2_channel, ced);
277} 277}
278 278
279static void sh_mtu2_clock_event_mode(enum clock_event_mode mode, 279static int sh_mtu2_clock_event_shutdown(struct clock_event_device *ced)
280 struct clock_event_device *ced)
281{ 280{
282 struct sh_mtu2_channel *ch = ced_to_sh_mtu2(ced); 281 struct sh_mtu2_channel *ch = ced_to_sh_mtu2(ced);
283 int disabled = 0;
284 282
285 /* deal with old setting first */ 283 sh_mtu2_disable(ch);
286 switch (ced->mode) { 284 return 0;
287 case CLOCK_EVT_MODE_PERIODIC: 285}
286
287static int sh_mtu2_clock_event_set_periodic(struct clock_event_device *ced)
288{
289 struct sh_mtu2_channel *ch = ced_to_sh_mtu2(ced);
290
291 if (clockevent_state_periodic(ced))
288 sh_mtu2_disable(ch); 292 sh_mtu2_disable(ch);
289 disabled = 1;
290 break;
291 default:
292 break;
293 }
294 293
295 switch (mode) { 294 dev_info(&ch->mtu->pdev->dev, "ch%u: used for periodic clock events\n",
296 case CLOCK_EVT_MODE_PERIODIC: 295 ch->index);
297 dev_info(&ch->mtu->pdev->dev, 296 sh_mtu2_enable(ch);
298 "ch%u: used for periodic clock events\n", ch->index); 297 return 0;
299 sh_mtu2_enable(ch);
300 break;
301 case CLOCK_EVT_MODE_UNUSED:
302 if (!disabled)
303 sh_mtu2_disable(ch);
304 break;
305 case CLOCK_EVT_MODE_SHUTDOWN:
306 default:
307 break;
308 }
309} 298}
310 299
311static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced) 300static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced)
@@ -327,7 +316,8 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
327 ced->features = CLOCK_EVT_FEAT_PERIODIC; 316 ced->features = CLOCK_EVT_FEAT_PERIODIC;
328 ced->rating = 200; 317 ced->rating = 200;
329 ced->cpumask = cpu_possible_mask; 318 ced->cpumask = cpu_possible_mask;
330 ced->set_mode = sh_mtu2_clock_event_mode; 319 ced->set_state_shutdown = sh_mtu2_clock_event_shutdown;
320 ced->set_state_periodic = sh_mtu2_clock_event_set_periodic;
331 ced->suspend = sh_mtu2_clock_event_suspend; 321 ced->suspend = sh_mtu2_clock_event_suspend;
332 ced->resume = sh_mtu2_clock_event_resume; 322 ced->resume = sh_mtu2_clock_event_resume;
333 323
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index b6b8fa3cd211..469e776ec17a 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -240,7 +240,7 @@ static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id)
240 struct sh_tmu_channel *ch = dev_id; 240 struct sh_tmu_channel *ch = dev_id;
241 241
242 /* disable or acknowledge interrupt */ 242 /* disable or acknowledge interrupt */
243 if (ch->ced.mode == CLOCK_EVT_MODE_ONESHOT) 243 if (clockevent_state_oneshot(&ch->ced))
244 sh_tmu_write(ch, TCR, TCR_TPSC_CLK4); 244 sh_tmu_write(ch, TCR, TCR_TPSC_CLK4);
245 else 245 else
246 sh_tmu_write(ch, TCR, TCR_UNIE | TCR_TPSC_CLK4); 246 sh_tmu_write(ch, TCR, TCR_UNIE | TCR_TPSC_CLK4);
@@ -358,42 +358,38 @@ static void sh_tmu_clock_event_start(struct sh_tmu_channel *ch, int periodic)
358 } 358 }
359} 359}
360 360
361static void sh_tmu_clock_event_mode(enum clock_event_mode mode, 361static int sh_tmu_clock_event_shutdown(struct clock_event_device *ced)
362 struct clock_event_device *ced) 362{
363 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);
364
365 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
366 sh_tmu_disable(ch);
367 return 0;
368}
369
370static int sh_tmu_clock_event_set_state(struct clock_event_device *ced,
371 int periodic)
363{ 372{
364 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced); 373 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);
365 int disabled = 0;
366 374
367 /* deal with old setting first */ 375 /* deal with old setting first */
368 switch (ced->mode) { 376 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
369 case CLOCK_EVT_MODE_PERIODIC:
370 case CLOCK_EVT_MODE_ONESHOT:
371 sh_tmu_disable(ch); 377 sh_tmu_disable(ch);
372 disabled = 1;
373 break;
374 default:
375 break;
376 }
377 378
378 switch (mode) { 379 dev_info(&ch->tmu->pdev->dev, "ch%u: used for %s clock events\n",
379 case CLOCK_EVT_MODE_PERIODIC: 380 ch->index, periodic ? "periodic" : "oneshot");
380 dev_info(&ch->tmu->pdev->dev, 381 sh_tmu_clock_event_start(ch, periodic);
381 "ch%u: used for periodic clock events\n", ch->index); 382 return 0;
382 sh_tmu_clock_event_start(ch, 1); 383}
383 break; 384
384 case CLOCK_EVT_MODE_ONESHOT: 385static int sh_tmu_clock_event_set_oneshot(struct clock_event_device *ced)
385 dev_info(&ch->tmu->pdev->dev, 386{
386 "ch%u: used for oneshot clock events\n", ch->index); 387 return sh_tmu_clock_event_set_state(ced, 0);
387 sh_tmu_clock_event_start(ch, 0); 388}
388 break; 389
389 case CLOCK_EVT_MODE_UNUSED: 390static int sh_tmu_clock_event_set_periodic(struct clock_event_device *ced)
390 if (!disabled) 391{
391 sh_tmu_disable(ch); 392 return sh_tmu_clock_event_set_state(ced, 1);
392 break;
393 case CLOCK_EVT_MODE_SHUTDOWN:
394 default:
395 break;
396 }
397} 393}
398 394
399static int sh_tmu_clock_event_next(unsigned long delta, 395static int sh_tmu_clock_event_next(unsigned long delta,
@@ -401,7 +397,7 @@ static int sh_tmu_clock_event_next(unsigned long delta,
401{ 397{
402 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced); 398 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);
403 399
404 BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); 400 BUG_ON(!clockevent_state_oneshot(ced));
405 401
406 /* program new delta value */ 402 /* program new delta value */
407 sh_tmu_set_next(ch, delta, 0); 403 sh_tmu_set_next(ch, delta, 0);
@@ -430,7 +426,9 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch,
430 ced->rating = 200; 426 ced->rating = 200;
431 ced->cpumask = cpu_possible_mask; 427 ced->cpumask = cpu_possible_mask;
432 ced->set_next_event = sh_tmu_clock_event_next; 428 ced->set_next_event = sh_tmu_clock_event_next;
433 ced->set_mode = sh_tmu_clock_event_mode; 429 ced->set_state_shutdown = sh_tmu_clock_event_shutdown;
430 ced->set_state_periodic = sh_tmu_clock_event_set_periodic;
431 ced->set_state_oneshot = sh_tmu_clock_event_set_oneshot;
434 ced->suspend = sh_tmu_clock_event_suspend; 432 ced->suspend = sh_tmu_clock_event_suspend;
435 ced->resume = sh_tmu_clock_event_resume; 433 ced->resume = sh_tmu_clock_event_resume;
436 434
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
index 1928a8912584..6f3719d73390 100644
--- a/drivers/clocksource/sun4i_timer.c
+++ b/drivers/clocksource/sun4i_timer.c
@@ -81,25 +81,25 @@ static void sun4i_clkevt_time_start(u8 timer, bool periodic)
81 timer_base + TIMER_CTL_REG(timer)); 81 timer_base + TIMER_CTL_REG(timer));
82} 82}
83 83
84static void sun4i_clkevt_mode(enum clock_event_mode mode, 84static int sun4i_clkevt_shutdown(struct clock_event_device *evt)
85 struct clock_event_device *clk)
86{ 85{
87 switch (mode) { 86 sun4i_clkevt_time_stop(0);
88 case CLOCK_EVT_MODE_PERIODIC: 87 return 0;
89 sun4i_clkevt_time_stop(0); 88}
90 sun4i_clkevt_time_setup(0, ticks_per_jiffy); 89
91 sun4i_clkevt_time_start(0, true); 90static int sun4i_clkevt_set_oneshot(struct clock_event_device *evt)
92 break; 91{
93 case CLOCK_EVT_MODE_ONESHOT: 92 sun4i_clkevt_time_stop(0);
94 sun4i_clkevt_time_stop(0); 93 sun4i_clkevt_time_start(0, false);
95 sun4i_clkevt_time_start(0, false); 94 return 0;
96 break; 95}
97 case CLOCK_EVT_MODE_UNUSED: 96
98 case CLOCK_EVT_MODE_SHUTDOWN: 97static int sun4i_clkevt_set_periodic(struct clock_event_device *evt)
99 default: 98{
100 sun4i_clkevt_time_stop(0); 99 sun4i_clkevt_time_stop(0);
101 break; 100 sun4i_clkevt_time_setup(0, ticks_per_jiffy);
102 } 101 sun4i_clkevt_time_start(0, true);
102 return 0;
103} 103}
104 104
105static int sun4i_clkevt_next_event(unsigned long evt, 105static int sun4i_clkevt_next_event(unsigned long evt,
@@ -116,7 +116,10 @@ static struct clock_event_device sun4i_clockevent = {
116 .name = "sun4i_tick", 116 .name = "sun4i_tick",
117 .rating = 350, 117 .rating = 350,
118 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 118 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
119 .set_mode = sun4i_clkevt_mode, 119 .set_state_shutdown = sun4i_clkevt_shutdown,
120 .set_state_periodic = sun4i_clkevt_set_periodic,
121 .set_state_oneshot = sun4i_clkevt_set_oneshot,
122 .tick_resume = sun4i_clkevt_shutdown,
120 .set_next_event = sun4i_clkevt_next_event, 123 .set_next_event = sun4i_clkevt_next_event,
121}; 124};
122 125
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 8bdbc45c6dad..d28d2fe798d5 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -91,55 +91,62 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
91 */ 91 */
92static u32 timer_clock; 92static u32 timer_clock;
93 93
94static void tc_mode(enum clock_event_mode m, struct clock_event_device *d) 94static int tc_shutdown(struct clock_event_device *d)
95{ 95{
96 struct tc_clkevt_device *tcd = to_tc_clkevt(d); 96 struct tc_clkevt_device *tcd = to_tc_clkevt(d);
97 void __iomem *regs = tcd->regs; 97 void __iomem *regs = tcd->regs;
98 98
99 if (tcd->clkevt.mode == CLOCK_EVT_MODE_PERIODIC 99 __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
100 || tcd->clkevt.mode == CLOCK_EVT_MODE_ONESHOT) { 100 __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
101 __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); 101 clk_disable(tcd->clk);
102 __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
103 clk_disable(tcd->clk);
104 }
105 102
106 switch (m) { 103 return 0;
104}
107 105
108 /* By not making the gentime core emulate periodic mode on top 106static int tc_set_oneshot(struct clock_event_device *d)
109 * of oneshot, we get lower overhead and improved accuracy. 107{
110 */ 108 struct tc_clkevt_device *tcd = to_tc_clkevt(d);
111 case CLOCK_EVT_MODE_PERIODIC: 109 void __iomem *regs = tcd->regs;
112 clk_enable(tcd->clk);
113 110
114 /* slow clock, count up to RC, then irq and restart */ 111 if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
115 __raw_writel(timer_clock 112 tc_shutdown(d);
116 | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
117 regs + ATMEL_TC_REG(2, CMR));
118 __raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
119 113
120 /* Enable clock and interrupts on RC compare */ 114 clk_enable(tcd->clk);
121 __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
122 115
123 /* go go gadget! */ 116 /* slow clock, count up to RC, then irq and stop */
124 __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, 117 __raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
125 regs + ATMEL_TC_REG(2, CCR)); 118 ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR));
126 break; 119 __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
127 120
128 case CLOCK_EVT_MODE_ONESHOT: 121 /* set_next_event() configures and starts the timer */
129 clk_enable(tcd->clk); 122 return 0;
123}
130 124
131 /* slow clock, count up to RC, then irq and stop */ 125static int tc_set_periodic(struct clock_event_device *d)
132 __raw_writel(timer_clock | ATMEL_TC_CPCSTOP 126{
133 | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, 127 struct tc_clkevt_device *tcd = to_tc_clkevt(d);
134 regs + ATMEL_TC_REG(2, CMR)); 128 void __iomem *regs = tcd->regs;
135 __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
136 129
137 /* set_next_event() configures and starts the timer */ 130 if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
138 break; 131 tc_shutdown(d);
139 132
140 default: 133 /* By not making the gentime core emulate periodic mode on top
141 break; 134 * of oneshot, we get lower overhead and improved accuracy.
142 } 135 */
136 clk_enable(tcd->clk);
137
138 /* slow clock, count up to RC, then irq and restart */
139 __raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
140 regs + ATMEL_TC_REG(2, CMR));
141 __raw_writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
142
143 /* Enable clock and interrupts on RC compare */
144 __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
145
146 /* go go gadget! */
147 __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, regs +
148 ATMEL_TC_REG(2, CCR));
149 return 0;
143} 150}
144 151
145static int tc_next_event(unsigned long delta, struct clock_event_device *d) 152static int tc_next_event(unsigned long delta, struct clock_event_device *d)
@@ -154,13 +161,15 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
154 161
155static struct tc_clkevt_device clkevt = { 162static struct tc_clkevt_device clkevt = {
156 .clkevt = { 163 .clkevt = {
157 .name = "tc_clkevt", 164 .name = "tc_clkevt",
158 .features = CLOCK_EVT_FEAT_PERIODIC 165 .features = CLOCK_EVT_FEAT_PERIODIC |
159 | CLOCK_EVT_FEAT_ONESHOT, 166 CLOCK_EVT_FEAT_ONESHOT,
160 /* Should be lower than at91rm9200's system timer */ 167 /* Should be lower than at91rm9200's system timer */
161 .rating = 125, 168 .rating = 125,
162 .set_next_event = tc_next_event, 169 .set_next_event = tc_next_event,
163 .set_mode = tc_mode, 170 .set_state_shutdown = tc_shutdown,
171 .set_state_periodic = tc_set_periodic,
172 .set_state_oneshot = tc_set_oneshot,
164 }, 173 },
165}; 174};
166 175
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index 5a112d72fc2d..6ebda1177e79 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -72,33 +72,36 @@ static int tegra_timer_set_next_event(unsigned long cycles,
72 return 0; 72 return 0;
73} 73}
74 74
75static void tegra_timer_set_mode(enum clock_event_mode mode, 75static inline void timer_shutdown(struct clock_event_device *evt)
76 struct clock_event_device *evt)
77{ 76{
78 u32 reg;
79
80 timer_writel(0, TIMER3_BASE + TIMER_PTV); 77 timer_writel(0, TIMER3_BASE + TIMER_PTV);
78}
81 79
82 switch (mode) { 80static int tegra_timer_shutdown(struct clock_event_device *evt)
83 case CLOCK_EVT_MODE_PERIODIC: 81{
84 reg = 0xC0000000 | ((1000000/HZ)-1); 82 timer_shutdown(evt);
85 timer_writel(reg, TIMER3_BASE + TIMER_PTV); 83 return 0;
86 break; 84}
87 case CLOCK_EVT_MODE_ONESHOT: 85
88 break; 86static int tegra_timer_set_periodic(struct clock_event_device *evt)
89 case CLOCK_EVT_MODE_UNUSED: 87{
90 case CLOCK_EVT_MODE_SHUTDOWN: 88 u32 reg = 0xC0000000 | ((1000000 / HZ) - 1);
91 case CLOCK_EVT_MODE_RESUME: 89
92 break; 90 timer_shutdown(evt);
93 } 91 timer_writel(reg, TIMER3_BASE + TIMER_PTV);
92 return 0;
94} 93}
95 94
96static struct clock_event_device tegra_clockevent = { 95static struct clock_event_device tegra_clockevent = {
97 .name = "timer0", 96 .name = "timer0",
98 .rating = 300, 97 .rating = 300,
99 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 98 .features = CLOCK_EVT_FEAT_ONESHOT |
100 .set_next_event = tegra_timer_set_next_event, 99 CLOCK_EVT_FEAT_PERIODIC,
101 .set_mode = tegra_timer_set_mode, 100 .set_next_event = tegra_timer_set_next_event,
101 .set_state_shutdown = tegra_timer_shutdown,
102 .set_state_periodic = tegra_timer_set_periodic,
103 .set_state_oneshot = tegra_timer_shutdown,
104 .tick_resume = tegra_timer_shutdown,
102}; 105};
103 106
104static u64 notrace tegra_read_sched_clock(void) 107static u64 notrace tegra_read_sched_clock(void)
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 0c8c5e337540..2162796fd504 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -121,33 +121,33 @@ armada_370_xp_clkevt_next_event(unsigned long delta,
121 return 0; 121 return 0;
122} 122}
123 123
124static void 124static int armada_370_xp_clkevt_shutdown(struct clock_event_device *evt)
125armada_370_xp_clkevt_mode(enum clock_event_mode mode,
126 struct clock_event_device *dev)
127{ 125{
128 if (mode == CLOCK_EVT_MODE_PERIODIC) { 126 /*
127 * Disable timer.
128 */
129 local_timer_ctrl_clrset(TIMER0_EN, 0);
129 130
130 /* 131 /*
131 * Setup timer to fire at 1/HZ intervals. 132 * ACK pending timer interrupt.
132 */ 133 */
133 writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF); 134 writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
134 writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF); 135 return 0;
136}
135 137
136 /* 138static int armada_370_xp_clkevt_set_periodic(struct clock_event_device *evt)
137 * Enable timer. 139{
138 */ 140 /*
139 local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); 141 * Setup timer to fire at 1/HZ intervals.
140 } else { 142 */
141 /* 143 writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF);
142 * Disable timer. 144 writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF);
143 */
144 local_timer_ctrl_clrset(TIMER0_EN, 0);
145 145
146 /* 146 /*
147 * ACK pending timer interrupt. 147 * Enable timer.
148 */ 148 */
149 writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); 149 local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask);
150 } 150 return 0;
151} 151}
152 152
153static int armada_370_xp_clkevt_irq; 153static int armada_370_xp_clkevt_irq;
@@ -185,7 +185,10 @@ static int armada_370_xp_timer_setup(struct clock_event_device *evt)
185 evt->shift = 32, 185 evt->shift = 32,
186 evt->rating = 300, 186 evt->rating = 300,
187 evt->set_next_event = armada_370_xp_clkevt_next_event, 187 evt->set_next_event = armada_370_xp_clkevt_next_event,
188 evt->set_mode = armada_370_xp_clkevt_mode, 188 evt->set_state_shutdown = armada_370_xp_clkevt_shutdown;
189 evt->set_state_periodic = armada_370_xp_clkevt_set_periodic;
190 evt->set_state_oneshot = armada_370_xp_clkevt_shutdown;
191 evt->tick_resume = armada_370_xp_clkevt_shutdown;
189 evt->irq = armada_370_xp_clkevt_irq; 192 evt->irq = armada_370_xp_clkevt_irq;
190 evt->cpumask = cpumask_of(cpu); 193 evt->cpumask = cpumask_of(cpu);
191 194
@@ -197,7 +200,7 @@ static int armada_370_xp_timer_setup(struct clock_event_device *evt)
197 200
198static void armada_370_xp_timer_stop(struct clock_event_device *evt) 201static void armada_370_xp_timer_stop(struct clock_event_device *evt)
199{ 202{
200 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 203 evt->set_state_shutdown(evt);
201 disable_percpu_irq(evt->irq); 204 disable_percpu_irq(evt->irq);
202} 205}
203 206
diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c
index 5b6e3d5644c9..b06e4c2be406 100644
--- a/drivers/clocksource/time-efm32.c
+++ b/drivers/clocksource/time-efm32.c
@@ -48,40 +48,42 @@ struct efm32_clock_event_ddata {
48 unsigned periodic_top; 48 unsigned periodic_top;
49}; 49};
50 50
51static void efm32_clock_event_set_mode(enum clock_event_mode mode, 51static int efm32_clock_event_shutdown(struct clock_event_device *evtdev)
52 struct clock_event_device *evtdev)
53{ 52{
54 struct efm32_clock_event_ddata *ddata = 53 struct efm32_clock_event_ddata *ddata =
55 container_of(evtdev, struct efm32_clock_event_ddata, evtdev); 54 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
56 55
57 switch (mode) { 56 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
58 case CLOCK_EVT_MODE_PERIODIC: 57 return 0;
59 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 58}
60 writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP); 59
61 writel_relaxed(TIMERn_CTRL_PRESC_1024 | 60static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev)
62 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | 61{
63 TIMERn_CTRL_MODE_DOWN, 62 struct efm32_clock_event_ddata *ddata =
64 ddata->base + TIMERn_CTRL); 63 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
65 writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); 64
66 break; 65 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
67 66 writel_relaxed(TIMERn_CTRL_PRESC_1024 |
68 case CLOCK_EVT_MODE_ONESHOT: 67 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
69 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 68 TIMERn_CTRL_OSMEN |
70 writel_relaxed(TIMERn_CTRL_PRESC_1024 | 69 TIMERn_CTRL_MODE_DOWN,
71 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | 70 ddata->base + TIMERn_CTRL);
72 TIMERn_CTRL_OSMEN | 71 return 0;
73 TIMERn_CTRL_MODE_DOWN, 72}
74 ddata->base + TIMERn_CTRL); 73
75 break; 74static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev)
76 75{
77 case CLOCK_EVT_MODE_UNUSED: 76 struct efm32_clock_event_ddata *ddata =
78 case CLOCK_EVT_MODE_SHUTDOWN: 77 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
79 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 78
80 break; 79 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
81 80 writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
82 case CLOCK_EVT_MODE_RESUME: 81 writel_relaxed(TIMERn_CTRL_PRESC_1024 |
83 break; 82 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
84 } 83 TIMERn_CTRL_MODE_DOWN,
84 ddata->base + TIMERn_CTRL);
85 writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
86 return 0;
85} 87}
86 88
87static int efm32_clock_event_set_next_event(unsigned long evt, 89static int efm32_clock_event_set_next_event(unsigned long evt,
@@ -112,7 +114,9 @@ static struct efm32_clock_event_ddata clock_event_ddata = {
112 .evtdev = { 114 .evtdev = {
113 .name = "efm32 clockevent", 115 .name = "efm32 clockevent",
114 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 116 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
115 .set_mode = efm32_clock_event_set_mode, 117 .set_state_shutdown = efm32_clock_event_shutdown,
118 .set_state_periodic = efm32_clock_event_set_periodic,
119 .set_state_oneshot = efm32_clock_event_set_oneshot,
116 .set_next_event = efm32_clock_event_set_next_event, 120 .set_next_event = efm32_clock_event_set_next_event,
117 .rating = 200, 121 .rating = 200,
118 }, 122 },
diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c
index 0b3ce0399c51..0ece7427b497 100644
--- a/drivers/clocksource/time-orion.c
+++ b/drivers/clocksource/time-orion.c
@@ -60,30 +60,36 @@ static int orion_clkevt_next_event(unsigned long delta,
60 return 0; 60 return 0;
61} 61}
62 62
63static void orion_clkevt_mode(enum clock_event_mode mode, 63static int orion_clkevt_shutdown(struct clock_event_device *dev)
64 struct clock_event_device *dev)
65{ 64{
66 if (mode == CLOCK_EVT_MODE_PERIODIC) { 65 /* disable timer */
67 /* setup and enable periodic timer at 1/HZ intervals */ 66 atomic_io_modify(timer_base + TIMER_CTRL,
68 writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); 67 TIMER1_RELOAD_EN | TIMER1_EN, 0);
69 writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); 68 return 0;
70 atomic_io_modify(timer_base + TIMER_CTRL, 69}
71 TIMER1_RELOAD_EN | TIMER1_EN, 70
72 TIMER1_RELOAD_EN | TIMER1_EN); 71static int orion_clkevt_set_periodic(struct clock_event_device *dev)
73 } else { 72{
74 /* disable timer */ 73 /* setup and enable periodic timer at 1/HZ intervals */
75 atomic_io_modify(timer_base + TIMER_CTRL, 74 writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD);
76 TIMER1_RELOAD_EN | TIMER1_EN, 0); 75 writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL);
77 } 76 atomic_io_modify(timer_base + TIMER_CTRL,
77 TIMER1_RELOAD_EN | TIMER1_EN,
78 TIMER1_RELOAD_EN | TIMER1_EN);
79 return 0;
78} 80}
79 81
80static struct clock_event_device orion_clkevt = { 82static struct clock_event_device orion_clkevt = {
81 .name = "orion_event", 83 .name = "orion_event",
82 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 84 .features = CLOCK_EVT_FEAT_ONESHOT |
83 .shift = 32, 85 CLOCK_EVT_FEAT_PERIODIC,
84 .rating = 300, 86 .shift = 32,
85 .set_next_event = orion_clkevt_next_event, 87 .rating = 300,
86 .set_mode = orion_clkevt_mode, 88 .set_next_event = orion_clkevt_next_event,
89 .set_state_shutdown = orion_clkevt_shutdown,
90 .set_state_periodic = orion_clkevt_set_periodic,
91 .set_state_oneshot = orion_clkevt_shutdown,
92 .tick_resume = orion_clkevt_shutdown,
87}; 93};
88 94
89static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) 95static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id)
diff --git a/drivers/clocksource/timer-atlas7.c b/drivers/clocksource/timer-atlas7.c
index 60f9de3438b0..27fa13680be1 100644
--- a/drivers/clocksource/timer-atlas7.c
+++ b/drivers/clocksource/timer-atlas7.c
@@ -76,7 +76,7 @@ static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
76 /* clear timer interrupt */ 76 /* clear timer interrupt */
77 writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); 77 writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
78 78
79 if (ce->mode == CLOCK_EVT_MODE_ONESHOT) 79 if (clockevent_state_oneshot(ce))
80 sirfsoc_timer_count_disable(cpu); 80 sirfsoc_timer_count_disable(cpu);
81 81
82 ce->event_handler(ce); 82 ce->event_handler(ce);
@@ -117,18 +117,11 @@ static int sirfsoc_timer_set_next_event(unsigned long delta,
117 return 0; 117 return 0;
118} 118}
119 119
120static void sirfsoc_timer_set_mode(enum clock_event_mode mode, 120/* Oneshot is enabled in set_next_event */
121 struct clock_event_device *ce) 121static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
122{ 122{
123 switch (mode) {
124 case CLOCK_EVT_MODE_ONESHOT:
125 /* enable in set_next_event */
126 break;
127 default:
128 break;
129 }
130
131 sirfsoc_timer_count_disable(smp_processor_id()); 123 sirfsoc_timer_count_disable(smp_processor_id());
124 return 0;
132} 125}
133 126
134static void sirfsoc_clocksource_suspend(struct clocksource *cs) 127static void sirfsoc_clocksource_suspend(struct clocksource *cs)
@@ -193,7 +186,9 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
193 ce->name = "local_timer"; 186 ce->name = "local_timer";
194 ce->features = CLOCK_EVT_FEAT_ONESHOT; 187 ce->features = CLOCK_EVT_FEAT_ONESHOT;
195 ce->rating = 200; 188 ce->rating = 200;
196 ce->set_mode = sirfsoc_timer_set_mode; 189 ce->set_state_shutdown = sirfsoc_timer_shutdown;
190 ce->set_state_oneshot = sirfsoc_timer_shutdown;
191 ce->tick_resume = sirfsoc_timer_shutdown;
197 ce->set_next_event = sirfsoc_timer_set_next_event; 192 ce->set_next_event = sirfsoc_timer_set_next_event;
198 clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60); 193 clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60);
199 ce->max_delta_ns = clockevent_delta2ns(-2, ce); 194 ce->max_delta_ns = clockevent_delta2ns(-2, ce);
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c
index c0304ff608b0..d911c5dca8f1 100644
--- a/drivers/clocksource/timer-atmel-pit.c
+++ b/drivers/clocksource/timer-atmel-pit.c
@@ -90,33 +90,27 @@ static cycle_t read_pit_clk(struct clocksource *cs)
90 return elapsed; 90 return elapsed;
91} 91}
92 92
93static int pit_clkevt_shutdown(struct clock_event_device *dev)
94{
95 struct pit_data *data = clkevt_to_pit_data(dev);
96
97 /* disable irq, leaving the clocksource active */
98 pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN);
99 return 0;
100}
101
93/* 102/*
94 * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) 103 * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
95 */ 104 */
96static void 105static int pit_clkevt_set_periodic(struct clock_event_device *dev)
97pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
98{ 106{
99 struct pit_data *data = clkevt_to_pit_data(dev); 107 struct pit_data *data = clkevt_to_pit_data(dev);
100 108
101 switch (mode) { 109 /* update clocksource counter */
102 case CLOCK_EVT_MODE_PERIODIC: 110 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR));
103 /* update clocksource counter */ 111 pit_write(data->base, AT91_PIT_MR,
104 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); 112 (data->cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN);
105 pit_write(data->base, AT91_PIT_MR, 113 return 0;
106 (data->cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN);
107 break;
108 case CLOCK_EVT_MODE_ONESHOT:
109 BUG();
110 /* FALLTHROUGH */
111 case CLOCK_EVT_MODE_SHUTDOWN:
112 case CLOCK_EVT_MODE_UNUSED:
113 /* disable irq, leaving the clocksource active */
114 pit_write(data->base, AT91_PIT_MR,
115 (data->cycle - 1) | AT91_PIT_PITEN);
116 break;
117 case CLOCK_EVT_MODE_RESUME:
118 break;
119 }
120} 114}
121 115
122static void at91sam926x_pit_suspend(struct clock_event_device *cedev) 116static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
@@ -162,7 +156,7 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
162 WARN_ON_ONCE(!irqs_disabled()); 156 WARN_ON_ONCE(!irqs_disabled());
163 157
164 /* The PIT interrupt may be disabled, and is shared */ 158 /* The PIT interrupt may be disabled, and is shared */
165 if ((data->clkevt.mode == CLOCK_EVT_MODE_PERIODIC) && 159 if (clockevent_state_periodic(&data->clkevt) &&
166 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) { 160 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) {
167 unsigned nr_ticks; 161 unsigned nr_ticks;
168 162
@@ -208,8 +202,8 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data)
208 data->clksrc.mask = CLOCKSOURCE_MASK(bits); 202 data->clksrc.mask = CLOCKSOURCE_MASK(bits);
209 data->clksrc.name = "pit"; 203 data->clksrc.name = "pit";
210 data->clksrc.rating = 175; 204 data->clksrc.rating = 175;
211 data->clksrc.read = read_pit_clk, 205 data->clksrc.read = read_pit_clk;
212 data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS, 206 data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
213 clocksource_register_hz(&data->clksrc, pit_rate); 207 clocksource_register_hz(&data->clksrc, pit_rate);
214 208
215 /* Set up irq handler */ 209 /* Set up irq handler */
@@ -227,7 +221,8 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data)
227 data->clkevt.rating = 100; 221 data->clkevt.rating = 100;
228 data->clkevt.cpumask = cpumask_of(0); 222 data->clkevt.cpumask = cpumask_of(0);
229 223
230 data->clkevt.set_mode = pit_clkevt_mode; 224 data->clkevt.set_state_shutdown = pit_clkevt_shutdown;
225 data->clkevt.set_state_periodic = pit_clkevt_set_periodic;
231 data->clkevt.resume = at91sam926x_pit_resume; 226 data->clkevt.resume = at91sam926x_pit_resume;
232 data->clkevt.suspend = at91sam926x_pit_suspend; 227 data->clkevt.suspend = at91sam926x_pit_suspend;
233 clockevents_register_device(&data->clkevt); 228 clockevents_register_device(&data->clkevt);
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 1692e17e096b..41b7b6dc1d0d 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -106,36 +106,47 @@ static struct clocksource clk32k = {
106 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 106 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
107}; 107};
108 108
109static void 109static void clkdev32k_disable_and_flush_irq(void)
110clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
111{ 110{
112 unsigned int val; 111 unsigned int val;
113 112
114 /* Disable and flush pending timer interrupts */ 113 /* Disable and flush pending timer interrupts */
115 regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); 114 regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
116 regmap_read(regmap_st, AT91_ST_SR, &val); 115 regmap_read(regmap_st, AT91_ST_SR, &val);
117
118 last_crtr = read_CRTR(); 116 last_crtr = read_CRTR();
119 switch (mode) { 117}
120 case CLOCK_EVT_MODE_PERIODIC: 118
121 /* PIT for periodic irqs; fixed rate of 1/HZ */ 119static int clkevt32k_shutdown(struct clock_event_device *evt)
122 irqmask = AT91_ST_PITS; 120{
123 regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH); 121 clkdev32k_disable_and_flush_irq();
124 break; 122 irqmask = 0;
125 case CLOCK_EVT_MODE_ONESHOT: 123 regmap_write(regmap_st, AT91_ST_IER, irqmask);
126 /* ALM for oneshot irqs, set by next_event() 124 return 0;
127 * before 32 seconds have passed 125}
128 */ 126
129 irqmask = AT91_ST_ALMS; 127static int clkevt32k_set_oneshot(struct clock_event_device *dev)
130 regmap_write(regmap_st, AT91_ST_RTAR, last_crtr); 128{
131 break; 129 clkdev32k_disable_and_flush_irq();
132 case CLOCK_EVT_MODE_SHUTDOWN: 130
133 case CLOCK_EVT_MODE_UNUSED: 131 /*
134 case CLOCK_EVT_MODE_RESUME: 132 * ALM for oneshot irqs, set by next_event()
135 irqmask = 0; 133 * before 32 seconds have passed.
136 break; 134 */
137 } 135 irqmask = AT91_ST_ALMS;
136 regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
138 regmap_write(regmap_st, AT91_ST_IER, irqmask); 137 regmap_write(regmap_st, AT91_ST_IER, irqmask);
138 return 0;
139}
140
141static int clkevt32k_set_periodic(struct clock_event_device *dev)
142{
143 clkdev32k_disable_and_flush_irq();
144
145 /* PIT for periodic irqs; fixed rate of 1/HZ */
146 irqmask = AT91_ST_PITS;
147 regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
148 regmap_write(regmap_st, AT91_ST_IER, irqmask);
149 return 0;
139} 150}
140 151
141static int 152static int
@@ -170,11 +181,15 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
170} 181}
171 182
172static struct clock_event_device clkevt = { 183static struct clock_event_device clkevt = {
173 .name = "at91_tick", 184 .name = "at91_tick",
174 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 185 .features = CLOCK_EVT_FEAT_PERIODIC |
175 .rating = 150, 186 CLOCK_EVT_FEAT_ONESHOT,
176 .set_next_event = clkevt32k_next_event, 187 .rating = 150,
177 .set_mode = clkevt32k_mode, 188 .set_next_event = clkevt32k_next_event,
189 .set_state_shutdown = clkevt32k_shutdown,
190 .set_state_periodic = clkevt32k_set_periodic,
191 .set_state_oneshot = clkevt32k_set_oneshot,
192 .tick_resume = clkevt32k_shutdown,
178}; 193};
179 194
180/* 195/*
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
index 7f8388cfa810..e73947f0f86d 100644
--- a/drivers/clocksource/timer-digicolor.c
+++ b/drivers/clocksource/timer-digicolor.c
@@ -87,27 +87,27 @@ static inline void dc_timer_set_count(struct clock_event_device *ce,
87 writel(count, dt->base + COUNT(dt->timer_id)); 87 writel(count, dt->base + COUNT(dt->timer_id));
88} 88}
89 89
90static void digicolor_clkevt_mode(enum clock_event_mode mode, 90static int digicolor_clkevt_shutdown(struct clock_event_device *ce)
91 struct clock_event_device *ce) 91{
92 dc_timer_disable(ce);
93 return 0;
94}
95
96static int digicolor_clkevt_set_oneshot(struct clock_event_device *ce)
97{
98 dc_timer_disable(ce);
99 dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
100 return 0;
101}
102
103static int digicolor_clkevt_set_periodic(struct clock_event_device *ce)
92{ 104{
93 struct digicolor_timer *dt = dc_timer(ce); 105 struct digicolor_timer *dt = dc_timer(ce);
94 106
95 switch (mode) { 107 dc_timer_disable(ce);
96 case CLOCK_EVT_MODE_PERIODIC: 108 dc_timer_set_count(ce, dt->ticks_per_jiffy);
97 dc_timer_disable(ce); 109 dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
98 dc_timer_set_count(ce, dt->ticks_per_jiffy); 110 return 0;
99 dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
100 break;
101 case CLOCK_EVT_MODE_ONESHOT:
102 dc_timer_disable(ce);
103 dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
104 break;
105 case CLOCK_EVT_MODE_UNUSED:
106 case CLOCK_EVT_MODE_SHUTDOWN:
107 default:
108 dc_timer_disable(ce);
109 break;
110 }
111} 111}
112 112
113static int digicolor_clkevt_next_event(unsigned long evt, 113static int digicolor_clkevt_next_event(unsigned long evt,
@@ -125,7 +125,10 @@ static struct digicolor_timer dc_timer_dev = {
125 .name = "digicolor_tick", 125 .name = "digicolor_tick",
126 .rating = 340, 126 .rating = 340,
127 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 127 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
128 .set_mode = digicolor_clkevt_mode, 128 .set_state_shutdown = digicolor_clkevt_shutdown,
129 .set_state_periodic = digicolor_clkevt_set_periodic,
130 .set_state_oneshot = digicolor_clkevt_set_oneshot,
131 .tick_resume = digicolor_clkevt_shutdown,
129 .set_next_event = digicolor_clkevt_next_event, 132 .set_next_event = digicolor_clkevt_next_event,
130 }, 133 },
131 .timer_id = TIMER_C, 134 .timer_id = TIMER_C,
diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c
index 86c7eb66bdfb..839aba92fc39 100644
--- a/drivers/clocksource/timer-imx-gpt.c
+++ b/drivers/clocksource/timer-imx-gpt.c
@@ -83,7 +83,6 @@ struct imx_timer {
83 struct clk *clk_ipg; 83 struct clk *clk_ipg;
84 const struct imx_gpt_data *gpt; 84 const struct imx_gpt_data *gpt;
85 struct clock_event_device ced; 85 struct clock_event_device ced;
86 enum clock_event_mode cem;
87 struct irqaction act; 86 struct irqaction act;
88}; 87};
89 88
@@ -212,18 +211,38 @@ static int v2_set_next_event(unsigned long evt,
212 -ETIME : 0; 211 -ETIME : 0;
213} 212}
214 213
214static int mxc_shutdown(struct clock_event_device *ced)
215{
216 struct imx_timer *imxtm = to_imx_timer(ced);
217 unsigned long flags;
218 u32 tcn;
219
220 /*
221 * The timer interrupt generation is disabled at least
222 * for enough time to call mxc_set_next_event()
223 */
224 local_irq_save(flags);
225
226 /* Disable interrupt in GPT module */
227 imxtm->gpt->gpt_irq_disable(imxtm);
228
229 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
230 /* Set event time into far-far future */
231 writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
232
233 /* Clear pending interrupt */
234 imxtm->gpt->gpt_irq_acknowledge(imxtm);
235
215#ifdef DEBUG 236#ifdef DEBUG
216static const char *clock_event_mode_label[] = { 237 printk(KERN_INFO "%s: changing mode\n", __func__);
217 [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
218 [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
219 [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
220 [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED",
221 [CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME",
222};
223#endif /* DEBUG */ 238#endif /* DEBUG */
224 239
225static void mxc_set_mode(enum clock_event_mode mode, 240 local_irq_restore(flags);
226 struct clock_event_device *ced) 241
242 return 0;
243}
244
245static int mxc_set_oneshot(struct clock_event_device *ced)
227{ 246{
228 struct imx_timer *imxtm = to_imx_timer(ced); 247 struct imx_timer *imxtm = to_imx_timer(ced);
229 unsigned long flags; 248 unsigned long flags;
@@ -237,7 +256,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
237 /* Disable interrupt in GPT module */ 256 /* Disable interrupt in GPT module */
238 imxtm->gpt->gpt_irq_disable(imxtm); 257 imxtm->gpt->gpt_irq_disable(imxtm);
239 258
240 if (mode != imxtm->cem) { 259 if (!clockevent_state_oneshot(ced)) {
241 u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn); 260 u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
242 /* Set event time into far-far future */ 261 /* Set event time into far-far future */
243 writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp); 262 writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
@@ -247,37 +266,19 @@ static void mxc_set_mode(enum clock_event_mode mode,
247 } 266 }
248 267
249#ifdef DEBUG 268#ifdef DEBUG
250 printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", 269 printk(KERN_INFO "%s: changing mode\n", __func__);
251 clock_event_mode_label[imxtm->cem],
252 clock_event_mode_label[mode]);
253#endif /* DEBUG */ 270#endif /* DEBUG */
254 271
255 /* Remember timer mode */
256 imxtm->cem = mode;
257 local_irq_restore(flags);
258
259 switch (mode) {
260 case CLOCK_EVT_MODE_PERIODIC:
261 printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
262 "supported for i.MX\n");
263 break;
264 case CLOCK_EVT_MODE_ONESHOT:
265 /* 272 /*
266 * Do not put overhead of interrupt enable/disable into 273 * Do not put overhead of interrupt enable/disable into
267 * mxc_set_next_event(), the core has about 4 minutes 274 * mxc_set_next_event(), the core has about 4 minutes
268 * to call mxc_set_next_event() or shutdown clock after 275 * to call mxc_set_next_event() or shutdown clock after
269 * mode switching 276 * mode switching
270 */ 277 */
271 local_irq_save(flags); 278 imxtm->gpt->gpt_irq_enable(imxtm);
272 imxtm->gpt->gpt_irq_enable(imxtm); 279 local_irq_restore(flags);
273 local_irq_restore(flags); 280
274 break; 281 return 0;
275 case CLOCK_EVT_MODE_SHUTDOWN:
276 case CLOCK_EVT_MODE_UNUSED:
277 case CLOCK_EVT_MODE_RESUME:
278 /* Left event sources disabled, no more interrupts appear */
279 break;
280 }
281} 282}
282 283
283/* 284/*
@@ -303,11 +304,11 @@ static int __init mxc_clockevent_init(struct imx_timer *imxtm)
303 struct clock_event_device *ced = &imxtm->ced; 304 struct clock_event_device *ced = &imxtm->ced;
304 struct irqaction *act = &imxtm->act; 305 struct irqaction *act = &imxtm->act;
305 306
306 imxtm->cem = CLOCK_EVT_MODE_UNUSED;
307
308 ced->name = "mxc_timer1"; 307 ced->name = "mxc_timer1";
309 ced->features = CLOCK_EVT_FEAT_ONESHOT; 308 ced->features = CLOCK_EVT_FEAT_ONESHOT;
310 ced->set_mode = mxc_set_mode; 309 ced->set_state_shutdown = mxc_shutdown;
310 ced->set_state_oneshot = mxc_set_oneshot;
311 ced->tick_resume = mxc_shutdown;
311 ced->set_next_event = imxtm->gpt->set_next_event; 312 ced->set_next_event = imxtm->gpt->set_next_event;
312 ced->rating = 200; 313 ced->rating = 200;
313 ced->cpumask = cpumask_of(0); 314 ced->cpumask = cpumask_of(0);
diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c
index a68866e0ecd4..3f59ac2180dc 100644
--- a/drivers/clocksource/timer-integrator-ap.c
+++ b/drivers/clocksource/timer-integrator-ap.c
@@ -75,33 +75,37 @@ static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
75 return IRQ_HANDLED; 75 return IRQ_HANDLED;
76} 76}
77 77
78static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) 78static int clkevt_shutdown(struct clock_event_device *evt)
79{ 79{
80 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; 80 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
81 81
82 /* Disable timer */ 82 /* Disable timer */
83 writel(ctrl, clkevt_base + TIMER_CTRL); 83 writel(ctrl, clkevt_base + TIMER_CTRL);
84 return 0;
85}
84 86
85 switch (mode) { 87static int clkevt_set_oneshot(struct clock_event_device *evt)
86 case CLOCK_EVT_MODE_PERIODIC: 88{
87 /* Enable the timer and start the periodic tick */ 89 u32 ctrl = readl(clkevt_base + TIMER_CTRL) &
88 writel(timer_reload, clkevt_base + TIMER_LOAD); 90 ~(TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC);
89 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; 91
90 writel(ctrl, clkevt_base + TIMER_CTRL); 92 /* Leave the timer disabled, .set_next_event will enable it */
91 break; 93 writel(ctrl, clkevt_base + TIMER_CTRL);
92 case CLOCK_EVT_MODE_ONESHOT: 94 return 0;
93 /* Leave the timer disabled, .set_next_event will enable it */ 95}
94 ctrl &= ~TIMER_CTRL_PERIODIC;
95 writel(ctrl, clkevt_base + TIMER_CTRL);
96 break;
97 case CLOCK_EVT_MODE_UNUSED:
98 case CLOCK_EVT_MODE_SHUTDOWN:
99 case CLOCK_EVT_MODE_RESUME:
100 default:
101 /* Just leave in disabled state */
102 break;
103 }
104 96
97static int clkevt_set_periodic(struct clock_event_device *evt)
98{
99 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
100
101 /* Disable timer */
102 writel(ctrl, clkevt_base + TIMER_CTRL);
103
104 /* Enable the timer and start the periodic tick */
105 writel(timer_reload, clkevt_base + TIMER_LOAD);
106 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
107 writel(ctrl, clkevt_base + TIMER_CTRL);
108 return 0;
105} 109}
106 110
107static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) 111static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
@@ -116,11 +120,15 @@ static int clkevt_set_next_event(unsigned long next, struct clock_event_device *
116} 120}
117 121
118static struct clock_event_device integrator_clockevent = { 122static struct clock_event_device integrator_clockevent = {
119 .name = "timer1", 123 .name = "timer1",
120 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 124 .features = CLOCK_EVT_FEAT_PERIODIC |
121 .set_mode = clkevt_set_mode, 125 CLOCK_EVT_FEAT_ONESHOT,
122 .set_next_event = clkevt_set_next_event, 126 .set_state_shutdown = clkevt_shutdown,
123 .rating = 300, 127 .set_state_periodic = clkevt_set_periodic,
128 .set_state_oneshot = clkevt_set_oneshot,
129 .tick_resume = clkevt_shutdown,
130 .set_next_event = clkevt_set_next_event,
131 .rating = 300,
124}; 132};
125 133
126static struct irqaction integrator_timer_irq = { 134static struct irqaction integrator_timer_irq = {
diff --git a/drivers/clocksource/timer-keystone.c b/drivers/clocksource/timer-keystone.c
index 0250354f7e55..edacf3902e10 100644
--- a/drivers/clocksource/timer-keystone.c
+++ b/drivers/clocksource/timer-keystone.c
@@ -72,10 +72,10 @@ static inline void keystone_timer_barrier(void)
72 72
73/** 73/**
74 * keystone_timer_config: configures timer to work in oneshot/periodic modes. 74 * keystone_timer_config: configures timer to work in oneshot/periodic modes.
75 * @ mode: mode to configure 75 * @ mask: mask of the mode to configure
76 * @ period: cycles number to configure for 76 * @ period: cycles number to configure for
77 */ 77 */
78static int keystone_timer_config(u64 period, enum clock_event_mode mode) 78static int keystone_timer_config(u64 period, int mask)
79{ 79{
80 u32 tcr; 80 u32 tcr;
81 u32 off; 81 u32 off;
@@ -84,16 +84,7 @@ static int keystone_timer_config(u64 period, enum clock_event_mode mode)
84 off = tcr & ~(TCR_ENAMODE_MASK); 84 off = tcr & ~(TCR_ENAMODE_MASK);
85 85
86 /* set enable mode */ 86 /* set enable mode */
87 switch (mode) { 87 tcr |= mask;
88 case CLOCK_EVT_MODE_ONESHOT:
89 tcr |= TCR_ENAMODE_ONESHOT_MASK;
90 break;
91 case CLOCK_EVT_MODE_PERIODIC:
92 tcr |= TCR_ENAMODE_PERIODIC_MASK;
93 break;
94 default:
95 return -1;
96 }
97 88
98 /* disable timer */ 89 /* disable timer */
99 keystone_timer_writel(off, TCR); 90 keystone_timer_writel(off, TCR);
@@ -138,24 +129,19 @@ static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id)
138static int keystone_set_next_event(unsigned long cycles, 129static int keystone_set_next_event(unsigned long cycles,
139 struct clock_event_device *evt) 130 struct clock_event_device *evt)
140{ 131{
141 return keystone_timer_config(cycles, evt->mode); 132 return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK);
142} 133}
143 134
144static void keystone_set_mode(enum clock_event_mode mode, 135static int keystone_shutdown(struct clock_event_device *evt)
145 struct clock_event_device *evt)
146{ 136{
147 switch (mode) { 137 keystone_timer_disable();
148 case CLOCK_EVT_MODE_PERIODIC: 138 return 0;
149 keystone_timer_config(timer.hz_period, CLOCK_EVT_MODE_PERIODIC); 139}
150 break; 140
151 case CLOCK_EVT_MODE_UNUSED: 141static int keystone_set_periodic(struct clock_event_device *evt)
152 case CLOCK_EVT_MODE_SHUTDOWN: 142{
153 case CLOCK_EVT_MODE_ONESHOT: 143 keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK);
154 keystone_timer_disable(); 144 return 0;
155 break;
156 default:
157 break;
158 }
159} 145}
160 146
161static void __init keystone_timer_init(struct device_node *np) 147static void __init keystone_timer_init(struct device_node *np)
@@ -222,7 +208,9 @@ static void __init keystone_timer_init(struct device_node *np)
222 /* setup clockevent */ 208 /* setup clockevent */
223 event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 209 event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
224 event_dev->set_next_event = keystone_set_next_event; 210 event_dev->set_next_event = keystone_set_next_event;
225 event_dev->set_mode = keystone_set_mode; 211 event_dev->set_state_shutdown = keystone_shutdown;
212 event_dev->set_state_periodic = keystone_set_periodic;
213 event_dev->set_state_oneshot = keystone_shutdown;
226 event_dev->cpumask = cpu_all_mask; 214 event_dev->cpumask = cpu_all_mask;
227 event_dev->owner = THIS_MODULE; 215 event_dev->owner = THIS_MODULE;
228 event_dev->name = TIMER_NAME; 216 event_dev->name = TIMER_NAME;
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c
index ce18d570e1cd..78de982cc640 100644
--- a/drivers/clocksource/timer-prima2.c
+++ b/drivers/clocksource/timer-prima2.c
@@ -104,26 +104,21 @@ static int sirfsoc_timer_set_next_event(unsigned long delta,
104 return next - now > delta ? -ETIME : 0; 104 return next - now > delta ? -ETIME : 0;
105} 105}
106 106
107static void sirfsoc_timer_set_mode(enum clock_event_mode mode, 107static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
108 struct clock_event_device *ce)
109{ 108{
110 u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); 109 u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
111 switch (mode) { 110
112 case CLOCK_EVT_MODE_PERIODIC: 111 writel_relaxed(val & ~BIT(0),
113 WARN_ON(1); 112 sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
114 break; 113 return 0;
115 case CLOCK_EVT_MODE_ONESHOT: 114}
116 writel_relaxed(val | BIT(0), 115
117 sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); 116static int sirfsoc_timer_set_oneshot(struct clock_event_device *evt)
118 break; 117{
119 case CLOCK_EVT_MODE_SHUTDOWN: 118 u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
120 writel_relaxed(val & ~BIT(0), 119
121 sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); 120 writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
122 break; 121 return 0;
123 case CLOCK_EVT_MODE_UNUSED:
124 case CLOCK_EVT_MODE_RESUME:
125 break;
126 }
127} 122}
128 123
129static void sirfsoc_clocksource_suspend(struct clocksource *cs) 124static void sirfsoc_clocksource_suspend(struct clocksource *cs)
@@ -157,7 +152,8 @@ static struct clock_event_device sirfsoc_clockevent = {
157 .name = "sirfsoc_clockevent", 152 .name = "sirfsoc_clockevent",
158 .rating = 200, 153 .rating = 200,
159 .features = CLOCK_EVT_FEAT_ONESHOT, 154 .features = CLOCK_EVT_FEAT_ONESHOT,
160 .set_mode = sirfsoc_timer_set_mode, 155 .set_state_shutdown = sirfsoc_timer_shutdown,
156 .set_state_oneshot = sirfsoc_timer_set_oneshot,
161 .set_next_event = sirfsoc_timer_set_next_event, 157 .set_next_event = sirfsoc_timer_set_next_event,
162}; 158};
163 159
diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c
index ca02503f17d1..5f45b9adef60 100644
--- a/drivers/clocksource/timer-sp804.c
+++ b/drivers/clocksource/timer-sp804.c
@@ -133,50 +133,50 @@ static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id)
133 return IRQ_HANDLED; 133 return IRQ_HANDLED;
134} 134}
135 135
136static void sp804_set_mode(enum clock_event_mode mode, 136static inline void timer_shutdown(struct clock_event_device *evt)
137 struct clock_event_device *evt)
138{ 137{
139 unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; 138 writel(0, clkevt_base + TIMER_CTRL);
139}
140 140
141 writel(ctrl, clkevt_base + TIMER_CTRL); 141static int sp804_shutdown(struct clock_event_device *evt)
142{
143 timer_shutdown(evt);
144 return 0;
145}
142 146
143 switch (mode) { 147static int sp804_set_periodic(struct clock_event_device *evt)
144 case CLOCK_EVT_MODE_PERIODIC: 148{
145 writel(clkevt_reload, clkevt_base + TIMER_LOAD); 149 unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE |
146 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; 150 TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
147 break;
148
149 case CLOCK_EVT_MODE_ONESHOT:
150 /* period set, and timer enabled in 'next_event' hook */
151 ctrl |= TIMER_CTRL_ONESHOT;
152 break;
153
154 case CLOCK_EVT_MODE_UNUSED:
155 case CLOCK_EVT_MODE_SHUTDOWN:
156 default:
157 break;
158 }
159 151
152 timer_shutdown(evt);
153 writel(clkevt_reload, clkevt_base + TIMER_LOAD);
160 writel(ctrl, clkevt_base + TIMER_CTRL); 154 writel(ctrl, clkevt_base + TIMER_CTRL);
155 return 0;
161} 156}
162 157
163static int sp804_set_next_event(unsigned long next, 158static int sp804_set_next_event(unsigned long next,
164 struct clock_event_device *evt) 159 struct clock_event_device *evt)
165{ 160{
166 unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); 161 unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE |
162 TIMER_CTRL_ONESHOT | TIMER_CTRL_ENABLE;
167 163
168 writel(next, clkevt_base + TIMER_LOAD); 164 writel(next, clkevt_base + TIMER_LOAD);
169 writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); 165 writel(ctrl, clkevt_base + TIMER_CTRL);
170 166
171 return 0; 167 return 0;
172} 168}
173 169
174static struct clock_event_device sp804_clockevent = { 170static struct clock_event_device sp804_clockevent = {
175 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 171 .features = CLOCK_EVT_FEAT_PERIODIC |
176 CLOCK_EVT_FEAT_DYNIRQ, 172 CLOCK_EVT_FEAT_ONESHOT |
177 .set_mode = sp804_set_mode, 173 CLOCK_EVT_FEAT_DYNIRQ,
178 .set_next_event = sp804_set_next_event, 174 .set_state_shutdown = sp804_shutdown,
179 .rating = 300, 175 .set_state_periodic = sp804_set_periodic,
176 .set_state_oneshot = sp804_shutdown,
177 .tick_resume = sp804_shutdown,
178 .set_next_event = sp804_set_next_event,
179 .rating = 300,
180}; 180};
181 181
182static struct irqaction sp804_timer_irq = { 182static struct irqaction sp804_timer_irq = {
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index a97e8b50701c..f3dcb76799b4 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -40,24 +40,25 @@ struct stm32_clock_event_ddata {
40 void __iomem *base; 40 void __iomem *base;
41}; 41};
42 42
43static void stm32_clock_event_set_mode(enum clock_event_mode mode, 43static int stm32_clock_event_shutdown(struct clock_event_device *evtdev)
44 struct clock_event_device *evtdev)
45{ 44{
46 struct stm32_clock_event_ddata *data = 45 struct stm32_clock_event_ddata *data =
47 container_of(evtdev, struct stm32_clock_event_ddata, evtdev); 46 container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
48 void *base = data->base; 47 void *base = data->base;
49 48
50 switch (mode) { 49 writel_relaxed(0, base + TIM_CR1);
51 case CLOCK_EVT_MODE_PERIODIC: 50 return 0;
52 writel_relaxed(data->periodic_top, base + TIM_ARR); 51}
53 writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
54 break;
55 52
56 case CLOCK_EVT_MODE_ONESHOT: 53static int stm32_clock_event_set_periodic(struct clock_event_device *evtdev)
57 default: 54{
58 writel_relaxed(0, base + TIM_CR1); 55 struct stm32_clock_event_ddata *data =
59 break; 56 container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
60 } 57 void *base = data->base;
58
59 writel_relaxed(data->periodic_top, base + TIM_ARR);
60 writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
61 return 0;
61} 62}
62 63
63static int stm32_clock_event_set_next_event(unsigned long evt, 64static int stm32_clock_event_set_next_event(unsigned long evt,
@@ -88,7 +89,10 @@ static struct stm32_clock_event_ddata clock_event_ddata = {
88 .evtdev = { 89 .evtdev = {
89 .name = "stm32 clockevent", 90 .name = "stm32 clockevent",
90 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 91 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
91 .set_mode = stm32_clock_event_set_mode, 92 .set_state_shutdown = stm32_clock_event_shutdown,
93 .set_state_periodic = stm32_clock_event_set_periodic,
94 .set_state_oneshot = stm32_clock_event_shutdown,
95 .tick_resume = stm32_clock_event_shutdown,
92 .set_next_event = stm32_clock_event_set_next_event, 96 .set_next_event = stm32_clock_event_set_next_event,
93 .rating = 200, 97 .rating = 200,
94 }, 98 },
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index 0ffb4ea7c925..bca9573e036a 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -103,27 +103,31 @@ static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, boo
103 ce->timer.base + TIMER_CTL_REG(timer)); 103 ce->timer.base + TIMER_CTL_REG(timer));
104} 104}
105 105
106static void sun5i_clkevt_mode(enum clock_event_mode mode, 106static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
107 struct clock_event_device *clkevt)
108{ 107{
109 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt); 108 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
110 109
111 switch (mode) { 110 sun5i_clkevt_time_stop(ce, 0);
112 case CLOCK_EVT_MODE_PERIODIC: 111 return 0;
113 sun5i_clkevt_time_stop(ce, 0); 112}
114 sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy); 113
115 sun5i_clkevt_time_start(ce, 0, true); 114static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
116 break; 115{
117 case CLOCK_EVT_MODE_ONESHOT: 116 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
118 sun5i_clkevt_time_stop(ce, 0); 117
119 sun5i_clkevt_time_start(ce, 0, false); 118 sun5i_clkevt_time_stop(ce, 0);
120 break; 119 sun5i_clkevt_time_start(ce, 0, false);
121 case CLOCK_EVT_MODE_UNUSED: 120 return 0;
122 case CLOCK_EVT_MODE_SHUTDOWN: 121}
123 default: 122
124 sun5i_clkevt_time_stop(ce, 0); 123static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
125 break; 124{
126 } 125 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
126
127 sun5i_clkevt_time_stop(ce, 0);
128 sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
129 sun5i_clkevt_time_start(ce, 0, true);
130 return 0;
127} 131}
128 132
129static int sun5i_clkevt_next_event(unsigned long evt, 133static int sun5i_clkevt_next_event(unsigned long evt,
@@ -286,7 +290,10 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
286 ce->clkevt.name = node->name; 290 ce->clkevt.name = node->name;
287 ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 291 ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
288 ce->clkevt.set_next_event = sun5i_clkevt_next_event; 292 ce->clkevt.set_next_event = sun5i_clkevt_next_event;
289 ce->clkevt.set_mode = sun5i_clkevt_mode; 293 ce->clkevt.set_state_shutdown = sun5i_clkevt_shutdown;
294 ce->clkevt.set_state_periodic = sun5i_clkevt_set_periodic;
295 ce->clkevt.set_state_oneshot = sun5i_clkevt_set_oneshot;
296 ce->clkevt.tick_resume = sun5i_clkevt_shutdown;
290 ce->clkevt.rating = 340; 297 ce->clkevt.rating = 340;
291 ce->clkevt.irq = irq; 298 ce->clkevt.irq = irq;
292 ce->clkevt.cpumask = cpu_possible_mask; 299 ce->clkevt.cpumask = cpu_possible_mask;
diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c
index 5dcf756970e7..1744b243898a 100644
--- a/drivers/clocksource/timer-u300.c
+++ b/drivers/clocksource/timer-u300.c
@@ -187,85 +187,82 @@ struct u300_clockevent_data {
187 unsigned ticks_per_jiffy; 187 unsigned ticks_per_jiffy;
188}; 188};
189 189
190static int u300_shutdown(struct clock_event_device *evt)
191{
192 /* Disable interrupts on GP1 */
193 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
194 u300_timer_base + U300_TIMER_APP_GPT1IE);
195 /* Disable GP1 */
196 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
197 u300_timer_base + U300_TIMER_APP_DGPT1);
198 return 0;
199}
200
190/* 201/*
191 * The u300_set_mode() function is always called first, if we 202 * If we have oneshot timer active, the oneshot scheduling function
192 * have oneshot timer active, the oneshot scheduling function
193 * u300_set_next_event() is called immediately after. 203 * u300_set_next_event() is called immediately after.
194 */ 204 */
195static void u300_set_mode(enum clock_event_mode mode, 205static int u300_set_oneshot(struct clock_event_device *evt)
196 struct clock_event_device *evt) 206{
207 /* Just return; here? */
208 /*
209 * The actual event will be programmed by the next event hook,
210 * so we just set a dummy value somewhere at the end of the
211 * universe here.
212 */
213 /* Disable interrupts on GPT1 */
214 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
215 u300_timer_base + U300_TIMER_APP_GPT1IE);
216 /* Disable GP1 while we're reprogramming it. */
217 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
218 u300_timer_base + U300_TIMER_APP_DGPT1);
219 /*
220 * Expire far in the future, u300_set_next_event() will be
221 * called soon...
222 */
223 writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
224 /* We run one shot per tick here! */
225 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
226 u300_timer_base + U300_TIMER_APP_SGPT1M);
227 /* Enable interrupts for this timer */
228 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
229 u300_timer_base + U300_TIMER_APP_GPT1IE);
230 /* Enable timer */
231 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
232 u300_timer_base + U300_TIMER_APP_EGPT1);
233 return 0;
234}
235
236static int u300_set_periodic(struct clock_event_device *evt)
197{ 237{
198 struct u300_clockevent_data *cevdata = 238 struct u300_clockevent_data *cevdata =
199 container_of(evt, struct u300_clockevent_data, cevd); 239 container_of(evt, struct u300_clockevent_data, cevd);
200 240
201 switch (mode) { 241 /* Disable interrupts on GPT1 */
202 case CLOCK_EVT_MODE_PERIODIC: 242 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
203 /* Disable interrupts on GPT1 */ 243 u300_timer_base + U300_TIMER_APP_GPT1IE);
204 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, 244 /* Disable GP1 while we're reprogramming it. */
205 u300_timer_base + U300_TIMER_APP_GPT1IE); 245 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
206 /* Disable GP1 while we're reprogramming it. */ 246 u300_timer_base + U300_TIMER_APP_DGPT1);
207 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, 247 /*
208 u300_timer_base + U300_TIMER_APP_DGPT1); 248 * Set the periodic mode to a certain number of ticks per
209 /* 249 * jiffy.
210 * Set the periodic mode to a certain number of ticks per 250 */
211 * jiffy. 251 writel(cevdata->ticks_per_jiffy,
212 */ 252 u300_timer_base + U300_TIMER_APP_GPT1TC);
213 writel(cevdata->ticks_per_jiffy, 253 /*
214 u300_timer_base + U300_TIMER_APP_GPT1TC); 254 * Set continuous mode, so the timer keeps triggering
215 /* 255 * interrupts.
216 * Set continuous mode, so the timer keeps triggering 256 */
217 * interrupts. 257 writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
218 */ 258 u300_timer_base + U300_TIMER_APP_SGPT1M);
219 writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, 259 /* Enable timer interrupts */
220 u300_timer_base + U300_TIMER_APP_SGPT1M); 260 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
221 /* Enable timer interrupts */ 261 u300_timer_base + U300_TIMER_APP_GPT1IE);
222 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, 262 /* Then enable the OS timer again */
223 u300_timer_base + U300_TIMER_APP_GPT1IE); 263 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
224 /* Then enable the OS timer again */ 264 u300_timer_base + U300_TIMER_APP_EGPT1);
225 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, 265 return 0;
226 u300_timer_base + U300_TIMER_APP_EGPT1);
227 break;
228 case CLOCK_EVT_MODE_ONESHOT:
229 /* Just break; here? */
230 /*
231 * The actual event will be programmed by the next event hook,
232 * so we just set a dummy value somewhere at the end of the
233 * universe here.
234 */
235 /* Disable interrupts on GPT1 */
236 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
237 u300_timer_base + U300_TIMER_APP_GPT1IE);
238 /* Disable GP1 while we're reprogramming it. */
239 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
240 u300_timer_base + U300_TIMER_APP_DGPT1);
241 /*
242 * Expire far in the future, u300_set_next_event() will be
243 * called soon...
244 */
245 writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
246 /* We run one shot per tick here! */
247 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
248 u300_timer_base + U300_TIMER_APP_SGPT1M);
249 /* Enable interrupts for this timer */
250 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
251 u300_timer_base + U300_TIMER_APP_GPT1IE);
252 /* Enable timer */
253 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
254 u300_timer_base + U300_TIMER_APP_EGPT1);
255 break;
256 case CLOCK_EVT_MODE_UNUSED:
257 case CLOCK_EVT_MODE_SHUTDOWN:
258 /* Disable interrupts on GP1 */
259 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
260 u300_timer_base + U300_TIMER_APP_GPT1IE);
261 /* Disable GP1 */
262 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
263 u300_timer_base + U300_TIMER_APP_DGPT1);
264 break;
265 case CLOCK_EVT_MODE_RESUME:
266 /* Ignore this call */
267 break;
268 }
269} 266}
270 267
271/* 268/*
@@ -309,13 +306,15 @@ static int u300_set_next_event(unsigned long cycles,
309static struct u300_clockevent_data u300_clockevent_data = { 306static struct u300_clockevent_data u300_clockevent_data = {
310 /* Use general purpose timer 1 as clock event */ 307 /* Use general purpose timer 1 as clock event */
311 .cevd = { 308 .cevd = {
312 .name = "GPT1", 309 .name = "GPT1",
313 /* Reasonably fast and accurate clock event */ 310 /* Reasonably fast and accurate clock event */
314 .rating = 300, 311 .rating = 300,
315 .features = CLOCK_EVT_FEAT_PERIODIC | 312 .features = CLOCK_EVT_FEAT_PERIODIC |
316 CLOCK_EVT_FEAT_ONESHOT, 313 CLOCK_EVT_FEAT_ONESHOT,
317 .set_next_event = u300_set_next_event, 314 .set_next_event = u300_set_next_event,
318 .set_mode = u300_set_mode, 315 .set_state_shutdown = u300_shutdown,
316 .set_state_periodic = u300_set_periodic,
317 .set_state_oneshot = u300_set_oneshot,
319 }, 318 },
320}; 319};
321 320
diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c
index b45ac6229b57..f07ba9932171 100644
--- a/drivers/clocksource/vf_pit_timer.c
+++ b/drivers/clocksource/vf_pit_timer.c
@@ -86,20 +86,16 @@ static int pit_set_next_event(unsigned long delta,
86 return 0; 86 return 0;
87} 87}
88 88
89static void pit_set_mode(enum clock_event_mode mode, 89static int pit_shutdown(struct clock_event_device *evt)
90 struct clock_event_device *evt)
91{ 90{
92 switch (mode) { 91 pit_timer_disable();
93 case CLOCK_EVT_MODE_PERIODIC: 92 return 0;
94 pit_set_next_event(cycle_per_jiffy, evt); 93}
95 break; 94
96 case CLOCK_EVT_MODE_SHUTDOWN: 95static int pit_set_periodic(struct clock_event_device *evt)
97 case CLOCK_EVT_MODE_UNUSED: 96{
98 pit_timer_disable(); 97 pit_set_next_event(cycle_per_jiffy, evt);
99 break; 98 return 0;
100 default:
101 break;
102 }
103} 99}
104 100
105static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) 101static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
@@ -114,7 +110,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
114 * and start the counter again. So software need to disable the timer 110 * and start the counter again. So software need to disable the timer
115 * to stop the counter loop in ONESHOT mode. 111 * to stop the counter loop in ONESHOT mode.
116 */ 112 */
117 if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT)) 113 if (likely(clockevent_state_oneshot(evt)))
118 pit_timer_disable(); 114 pit_timer_disable();
119 115
120 evt->event_handler(evt); 116 evt->event_handler(evt);
@@ -125,7 +121,8 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
125static struct clock_event_device clockevent_pit = { 121static struct clock_event_device clockevent_pit = {
126 .name = "VF pit timer", 122 .name = "VF pit timer",
127 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 123 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
128 .set_mode = pit_set_mode, 124 .set_state_shutdown = pit_shutdown,
125 .set_state_periodic = pit_set_periodic,
129 .set_next_event = pit_set_next_event, 126 .set_next_event = pit_set_next_event,
130 .rating = 300, 127 .rating = 300,
131}; 128};
diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c
index 1098ed3b9b89..a92e94b40b5b 100644
--- a/drivers/clocksource/vt8500_timer.c
+++ b/drivers/clocksource/vt8500_timer.c
@@ -88,29 +88,20 @@ static int vt8500_timer_set_next_event(unsigned long cycles,
88 return 0; 88 return 0;
89} 89}
90 90
91static void vt8500_timer_set_mode(enum clock_event_mode mode, 91static int vt8500_shutdown(struct clock_event_device *evt)
92 struct clock_event_device *evt)
93{ 92{
94 switch (mode) { 93 writel(readl(regbase + TIMER_CTRL_VAL) | 1, regbase + TIMER_CTRL_VAL);
95 case CLOCK_EVT_MODE_RESUME: 94 writel(0, regbase + TIMER_IER_VAL);
96 case CLOCK_EVT_MODE_PERIODIC: 95 return 0;
97 break;
98 case CLOCK_EVT_MODE_ONESHOT:
99 case CLOCK_EVT_MODE_UNUSED:
100 case CLOCK_EVT_MODE_SHUTDOWN:
101 writel(readl(regbase + TIMER_CTRL_VAL) | 1,
102 regbase + TIMER_CTRL_VAL);
103 writel(0, regbase + TIMER_IER_VAL);
104 break;
105 }
106} 96}
107 97
108static struct clock_event_device clockevent = { 98static struct clock_event_device clockevent = {
109 .name = "vt8500_timer", 99 .name = "vt8500_timer",
110 .features = CLOCK_EVT_FEAT_ONESHOT, 100 .features = CLOCK_EVT_FEAT_ONESHOT,
111 .rating = 200, 101 .rating = 200,
112 .set_next_event = vt8500_timer_set_next_event, 102 .set_next_event = vt8500_timer_set_next_event,
113 .set_mode = vt8500_timer_set_mode, 103 .set_state_shutdown = vt8500_shutdown,
104 .set_state_oneshot = vt8500_shutdown,
114}; 105};
115 106
116static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id) 107static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
diff --git a/drivers/clocksource/zevio-timer.c b/drivers/clocksource/zevio-timer.c
index 7ce442148c3f..ceaa6133f9c2 100644
--- a/drivers/clocksource/zevio-timer.c
+++ b/drivers/clocksource/zevio-timer.c
@@ -76,32 +76,28 @@ static int zevio_timer_set_event(unsigned long delta,
76 return 0; 76 return 0;
77} 77}
78 78
79static void zevio_timer_set_mode(enum clock_event_mode mode, 79static int zevio_timer_shutdown(struct clock_event_device *dev)
80 struct clock_event_device *dev)
81{ 80{
82 struct zevio_timer *timer = container_of(dev, struct zevio_timer, 81 struct zevio_timer *timer = container_of(dev, struct zevio_timer,
83 clkevt); 82 clkevt);
84 83
85 switch (mode) { 84 /* Disable timer interrupts */
86 case CLOCK_EVT_MODE_RESUME: 85 writel(0, timer->interrupt_regs + IO_INTR_MSK);
87 case CLOCK_EVT_MODE_ONESHOT: 86 writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
88 /* Enable timer interrupts */ 87 /* Stop timer */
89 writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK); 88 writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
90 writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); 89 return 0;
91 break; 90}
92 case CLOCK_EVT_MODE_SHUTDOWN: 91
93 case CLOCK_EVT_MODE_UNUSED: 92static int zevio_timer_set_oneshot(struct clock_event_device *dev)
94 /* Disable timer interrupts */ 93{
95 writel(0, timer->interrupt_regs + IO_INTR_MSK); 94 struct zevio_timer *timer = container_of(dev, struct zevio_timer,
96 writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); 95 clkevt);
97 /* Stop timer */ 96
98 writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); 97 /* Enable timer interrupts */
99 break; 98 writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK);
100 case CLOCK_EVT_MODE_PERIODIC: 99 writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
101 default: 100 return 0;
102 /* Unsupported */
103 break;
104 }
105} 101}
106 102
107static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id) 103static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id)
@@ -162,7 +158,9 @@ static int __init zevio_timer_add(struct device_node *node)
162 if (timer->interrupt_regs && irqnr) { 158 if (timer->interrupt_regs && irqnr) {
163 timer->clkevt.name = timer->clockevent_name; 159 timer->clkevt.name = timer->clockevent_name;
164 timer->clkevt.set_next_event = zevio_timer_set_event; 160 timer->clkevt.set_next_event = zevio_timer_set_event;
165 timer->clkevt.set_mode = zevio_timer_set_mode; 161 timer->clkevt.set_state_shutdown = zevio_timer_shutdown;
162 timer->clkevt.set_state_oneshot = zevio_timer_set_oneshot;
163 timer->clkevt.tick_resume = zevio_timer_set_oneshot;
166 timer->clkevt.rating = 200; 164 timer->clkevt.rating = 200;
167 timer->clkevt.cpumask = cpu_all_mask; 165 timer->clkevt.cpumask = cpu_all_mask;
168 timer->clkevt.features = CLOCK_EVT_FEAT_ONESHOT; 166 timer->clkevt.features = CLOCK_EVT_FEAT_ONESHOT;
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 597a1e836f22..31ce435981fe 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -234,13 +234,10 @@ static inline int tick_check_broadcast_expired(void) { return 0; }
234static inline void tick_setup_hrtimer_broadcast(void) { } 234static inline void tick_setup_hrtimer_broadcast(void) { }
235# endif 235# endif
236 236
237extern int clockevents_notify(unsigned long reason, void *arg);
238
239#else /* !CONFIG_GENERIC_CLOCKEVENTS: */ 237#else /* !CONFIG_GENERIC_CLOCKEVENTS: */
240 238
241static inline void clockevents_suspend(void) { } 239static inline void clockevents_suspend(void) { }
242static inline void clockevents_resume(void) { } 240static inline void clockevents_resume(void) { }
243static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
244static inline int tick_check_broadcast_expired(void) { return 0; } 241static inline int tick_check_broadcast_expired(void) { return 0; }
245static inline void tick_setup_hrtimer_broadcast(void) { } 242static inline void tick_setup_hrtimer_broadcast(void) { }
246 243
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 9ea50da73513..5fdc55312334 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -409,9 +409,25 @@ static __always_inline unsigned long usecs_to_jiffies(const unsigned int u)
409 } 409 }
410} 410}
411 411
412extern unsigned long timespec_to_jiffies(const struct timespec *value); 412extern unsigned long timespec64_to_jiffies(const struct timespec64 *value);
413extern void jiffies_to_timespec(const unsigned long jiffies, 413extern void jiffies_to_timespec64(const unsigned long jiffies,
414 struct timespec *value); 414 struct timespec64 *value);
415static inline unsigned long timespec_to_jiffies(const struct timespec *value)
416{
417 struct timespec64 ts = timespec_to_timespec64(*value);
418
419 return timespec64_to_jiffies(&ts);
420}
421
422static inline void jiffies_to_timespec(const unsigned long jiffies,
423 struct timespec *value)
424{
425 struct timespec64 ts;
426
427 jiffies_to_timespec64(jiffies, &ts);
428 *value = timespec64_to_timespec(ts);
429}
430
415extern unsigned long timeval_to_jiffies(const struct timeval *value); 431extern unsigned long timeval_to_jiffies(const struct timeval *value);
416extern void jiffies_to_timeval(const unsigned long jiffies, 432extern void jiffies_to_timeval(const unsigned long jiffies,
417 struct timeval *value); 433 struct timeval *value);
diff --git a/include/linux/time64.h b/include/linux/time64.h
index 77b5df2acd2a..367d5af899e8 100644
--- a/include/linux/time64.h
+++ b/include/linux/time64.h
@@ -12,11 +12,18 @@ typedef __s64 time64_t;
12 */ 12 */
13#if __BITS_PER_LONG == 64 13#if __BITS_PER_LONG == 64
14# define timespec64 timespec 14# define timespec64 timespec
15#define itimerspec64 itimerspec
15#else 16#else
16struct timespec64 { 17struct timespec64 {
17 time64_t tv_sec; /* seconds */ 18 time64_t tv_sec; /* seconds */
18 long tv_nsec; /* nanoseconds */ 19 long tv_nsec; /* nanoseconds */
19}; 20};
21
22struct itimerspec64 {
23 struct timespec64 it_interval;
24 struct timespec64 it_value;
25};
26
20#endif 27#endif
21 28
22/* Parameters used to convert the timespec values: */ 29/* Parameters used to convert the timespec values: */
@@ -45,6 +52,16 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
45 return ts; 52 return ts;
46} 53}
47 54
55static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64)
56{
57 return *its64;
58}
59
60static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its)
61{
62 return *its;
63}
64
48# define timespec64_equal timespec_equal 65# define timespec64_equal timespec_equal
49# define timespec64_compare timespec_compare 66# define timespec64_compare timespec_compare
50# define set_normalized_timespec64 set_normalized_timespec 67# define set_normalized_timespec64 set_normalized_timespec
@@ -77,6 +94,24 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
77 return ret; 94 return ret;
78} 95}
79 96
97static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64)
98{
99 struct itimerspec ret;
100
101 ret.it_interval = timespec64_to_timespec(its64->it_interval);
102 ret.it_value = timespec64_to_timespec(its64->it_value);
103 return ret;
104}
105
106static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its)
107{
108 struct itimerspec64 ret;
109
110 ret.it_interval = timespec_to_timespec64(its->it_interval);
111 ret.it_value = timespec_to_timespec64(its->it_value);
112 return ret;
113}
114
80static inline int timespec64_equal(const struct timespec64 *a, 115static inline int timespec64_equal(const struct timespec64 *a,
81 const struct timespec64 *b) 116 const struct timespec64 *b)
82{ 117{
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 6e191e4e6ab6..ba0ae09cbb21 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -18,10 +18,17 @@ extern int do_sys_settimeofday(const struct timespec *tv,
18 * Kernel time accessors 18 * Kernel time accessors
19 */ 19 */
20unsigned long get_seconds(void); 20unsigned long get_seconds(void);
21struct timespec current_kernel_time(void); 21struct timespec64 current_kernel_time64(void);
22/* does not take xtime_lock */ 22/* does not take xtime_lock */
23struct timespec __current_kernel_time(void); 23struct timespec __current_kernel_time(void);
24 24
25static inline struct timespec current_kernel_time(void)
26{
27 struct timespec64 now = current_kernel_time64();
28
29 return timespec64_to_timespec(now);
30}
31
25/* 32/*
26 * timespec based interfaces 33 * timespec based interfaces
27 */ 34 */
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 5c7ae4b641c4..457a373e2181 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -183,7 +183,7 @@ struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base,
183 int pinned) 183 int pinned)
184{ 184{
185 if (pinned || !base->migration_enabled) 185 if (pinned || !base->migration_enabled)
186 return this_cpu_ptr(&hrtimer_bases); 186 return base;
187 return &per_cpu(hrtimer_bases, get_nohz_timer_target()); 187 return &per_cpu(hrtimer_bases, get_nohz_timer_target());
188} 188}
189#else 189#else
@@ -191,23 +191,32 @@ static inline
191struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, 191struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base,
192 int pinned) 192 int pinned)
193{ 193{
194 return this_cpu_ptr(&hrtimer_bases); 194 return base;
195} 195}
196#endif 196#endif
197 197
198/* 198/*
199 * Switch the timer base to the current CPU when possible. 199 * We switch the timer base to a power-optimized selected CPU target,
200 * if:
201 * - NO_HZ_COMMON is enabled
202 * - timer migration is enabled
203 * - the timer callback is not running
204 * - the timer is not the first expiring timer on the new target
205 *
206 * If one of the above requirements is not fulfilled we move the timer
207 * to the current CPU or leave it on the previously assigned CPU if
208 * the timer callback is currently running.
200 */ 209 */
201static inline struct hrtimer_clock_base * 210static inline struct hrtimer_clock_base *
202switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, 211switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
203 int pinned) 212 int pinned)
204{ 213{
205 struct hrtimer_cpu_base *new_cpu_base, *this_base; 214 struct hrtimer_cpu_base *new_cpu_base, *this_cpu_base;
206 struct hrtimer_clock_base *new_base; 215 struct hrtimer_clock_base *new_base;
207 int basenum = base->index; 216 int basenum = base->index;
208 217
209 this_base = this_cpu_ptr(&hrtimer_bases); 218 this_cpu_base = this_cpu_ptr(&hrtimer_bases);
210 new_cpu_base = get_target_base(this_base, pinned); 219 new_cpu_base = get_target_base(this_cpu_base, pinned);
211again: 220again:
212 new_base = &new_cpu_base->clock_base[basenum]; 221 new_base = &new_cpu_base->clock_base[basenum];
213 222
@@ -229,19 +238,19 @@ again:
229 raw_spin_unlock(&base->cpu_base->lock); 238 raw_spin_unlock(&base->cpu_base->lock);
230 raw_spin_lock(&new_base->cpu_base->lock); 239 raw_spin_lock(&new_base->cpu_base->lock);
231 240
232 if (new_cpu_base != this_base && 241 if (new_cpu_base != this_cpu_base &&
233 hrtimer_check_target(timer, new_base)) { 242 hrtimer_check_target(timer, new_base)) {
234 raw_spin_unlock(&new_base->cpu_base->lock); 243 raw_spin_unlock(&new_base->cpu_base->lock);
235 raw_spin_lock(&base->cpu_base->lock); 244 raw_spin_lock(&base->cpu_base->lock);
236 new_cpu_base = this_base; 245 new_cpu_base = this_cpu_base;
237 timer->base = base; 246 timer->base = base;
238 goto again; 247 goto again;
239 } 248 }
240 timer->base = new_base; 249 timer->base = new_base;
241 } else { 250 } else {
242 if (new_cpu_base != this_base && 251 if (new_cpu_base != this_cpu_base &&
243 hrtimer_check_target(timer, new_base)) { 252 hrtimer_check_target(timer, new_base)) {
244 new_cpu_base = this_base; 253 new_cpu_base = this_cpu_base;
245 goto again; 254 goto again;
246 } 255 }
247 } 256 }
@@ -679,14 +688,14 @@ static void retrigger_next_event(void *arg)
679/* 688/*
680 * Switch to high resolution mode 689 * Switch to high resolution mode
681 */ 690 */
682static int hrtimer_switch_to_hres(void) 691static void hrtimer_switch_to_hres(void)
683{ 692{
684 struct hrtimer_cpu_base *base = this_cpu_ptr(&hrtimer_bases); 693 struct hrtimer_cpu_base *base = this_cpu_ptr(&hrtimer_bases);
685 694
686 if (tick_init_highres()) { 695 if (tick_init_highres()) {
687 printk(KERN_WARNING "Could not switch to high resolution " 696 printk(KERN_WARNING "Could not switch to high resolution "
688 "mode on CPU %d\n", base->cpu); 697 "mode on CPU %d\n", base->cpu);
689 return 0; 698 return;
690 } 699 }
691 base->hres_active = 1; 700 base->hres_active = 1;
692 hrtimer_resolution = HIGH_RES_NSEC; 701 hrtimer_resolution = HIGH_RES_NSEC;
@@ -694,7 +703,6 @@ static int hrtimer_switch_to_hres(void)
694 tick_setup_sched_timer(); 703 tick_setup_sched_timer();
695 /* "Retrigger" the interrupt to get things going */ 704 /* "Retrigger" the interrupt to get things going */
696 retrigger_next_event(NULL); 705 retrigger_next_event(NULL);
697 return 1;
698} 706}
699 707
700static void clock_was_set_work(struct work_struct *work) 708static void clock_was_set_work(struct work_struct *work)
@@ -718,7 +726,7 @@ void clock_was_set_delayed(void)
718static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *b) { return 0; } 726static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *b) { return 0; }
719static inline int hrtimer_hres_active(void) { return 0; } 727static inline int hrtimer_hres_active(void) { return 0; }
720static inline int hrtimer_is_hres_enabled(void) { return 0; } 728static inline int hrtimer_is_hres_enabled(void) { return 0; }
721static inline int hrtimer_switch_to_hres(void) { return 0; } 729static inline void hrtimer_switch_to_hres(void) { }
722static inline void 730static inline void
723hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } 731hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { }
724static inline int hrtimer_reprogram(struct hrtimer *timer, 732static inline int hrtimer_reprogram(struct hrtimer *timer,
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index fb4d98c7fd43..df68cb875248 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -487,6 +487,11 @@ out:
487} 487}
488 488
489#ifdef CONFIG_GENERIC_CMOS_UPDATE 489#ifdef CONFIG_GENERIC_CMOS_UPDATE
490int __weak update_persistent_clock(struct timespec now)
491{
492 return -ENODEV;
493}
494
490int __weak update_persistent_clock64(struct timespec64 now64) 495int __weak update_persistent_clock64(struct timespec64 now64)
491{ 496{
492 struct timespec now; 497 struct timespec now;
diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c
index 3e7db49a2381..53d7184da0be 100644
--- a/kernel/time/tick-broadcast-hrtimer.c
+++ b/kernel/time/tick-broadcast-hrtimer.c
@@ -18,30 +18,23 @@
18 18
19static struct hrtimer bctimer; 19static struct hrtimer bctimer;
20 20
21static void bc_set_mode(enum clock_event_mode mode, 21static int bc_shutdown(struct clock_event_device *evt)
22 struct clock_event_device *bc)
23{ 22{
24 switch (mode) { 23 /*
25 case CLOCK_EVT_MODE_UNUSED: 24 * Note, we cannot cancel the timer here as we might
26 case CLOCK_EVT_MODE_SHUTDOWN: 25 * run into the following live lock scenario:
27 /* 26 *
28 * Note, we cannot cancel the timer here as we might 27 * cpu 0 cpu1
29 * run into the following live lock scenario: 28 * lock(broadcast_lock);
30 * 29 * hrtimer_interrupt()
31 * cpu 0 cpu1 30 * bc_handler()
32 * lock(broadcast_lock); 31 * tick_handle_oneshot_broadcast();
33 * hrtimer_interrupt() 32 * lock(broadcast_lock);
34 * bc_handler() 33 * hrtimer_cancel()
35 * tick_handle_oneshot_broadcast(); 34 * wait_for_callback()
36 * lock(broadcast_lock); 35 */
37 * hrtimer_cancel() 36 hrtimer_try_to_cancel(&bctimer);
38 * wait_for_callback() 37 return 0;
39 */
40 hrtimer_try_to_cancel(&bctimer);
41 break;
42 default:
43 break;
44 }
45} 38}
46 39
47/* 40/*
@@ -82,7 +75,7 @@ static int bc_set_next(ktime_t expires, struct clock_event_device *bc)
82} 75}
83 76
84static struct clock_event_device ce_broadcast_hrtimer = { 77static struct clock_event_device ce_broadcast_hrtimer = {
85 .set_mode = bc_set_mode, 78 .set_state_shutdown = bc_shutdown,
86 .set_next_ktime = bc_set_next, 79 .set_next_ktime = bc_set_next,
87 .features = CLOCK_EVT_FEAT_ONESHOT | 80 .features = CLOCK_EVT_FEAT_ONESHOT |
88 CLOCK_EVT_FEAT_KTIME | 81 CLOCK_EVT_FEAT_KTIME |
@@ -102,13 +95,11 @@ static enum hrtimer_restart bc_handler(struct hrtimer *t)
102{ 95{
103 ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer); 96 ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer);
104 97
105 switch (ce_broadcast_hrtimer.mode) { 98 if (clockevent_state_oneshot(&ce_broadcast_hrtimer))
106 case CLOCK_EVT_MODE_ONESHOT:
107 if (ce_broadcast_hrtimer.next_event.tv64 != KTIME_MAX) 99 if (ce_broadcast_hrtimer.next_event.tv64 != KTIME_MAX)
108 return HRTIMER_RESTART; 100 return HRTIMER_RESTART;
109 default: 101
110 return HRTIMER_NORESTART; 102 return HRTIMER_NORESTART;
111 }
112} 103}
113 104
114void tick_setup_hrtimer_broadcast(void) 105void tick_setup_hrtimer_broadcast(void)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index f8bf47571dda..d11c55b6ab7d 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -304,9 +304,6 @@ void tick_check_new_device(struct clock_event_device *newdev)
304 int cpu; 304 int cpu;
305 305
306 cpu = smp_processor_id(); 306 cpu = smp_processor_id();
307 if (!cpumask_test_cpu(cpu, newdev->cpumask))
308 goto out_bc;
309
310 td = &per_cpu(tick_cpu_device, cpu); 307 td = &per_cpu(tick_cpu_device, cpu);
311 curdev = td->evtdev; 308 curdev = td->evtdev;
312 309
diff --git a/kernel/time/time.c b/kernel/time/time.c
index ad1bf23e6eb7..86751c68e08d 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -291,26 +291,20 @@ EXPORT_SYMBOL(jiffies_to_usecs);
291 * @t: Timespec 291 * @t: Timespec
292 * @gran: Granularity in ns. 292 * @gran: Granularity in ns.
293 * 293 *
294 * Truncate a timespec to a granularity. gran must be smaller than a second. 294 * Truncate a timespec to a granularity. Always rounds down. gran must
295 * Always rounds down. 295 * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns).
296 *
297 * This function should be only used for timestamps returned by
298 * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because
299 * it doesn't handle the better resolution of the latter.
300 */ 296 */
301struct timespec timespec_trunc(struct timespec t, unsigned gran) 297struct timespec timespec_trunc(struct timespec t, unsigned gran)
302{ 298{
303 /* 299 /* Avoid division in the common cases 1 ns and 1 s. */
304 * Division is pretty slow so avoid it for common cases. 300 if (gran == 1) {
305 * Currently current_kernel_time() never returns better than
306 * jiffies resolution. Exploit that.
307 */
308 if (gran <= jiffies_to_usecs(1) * 1000) {
309 /* nothing */ 301 /* nothing */
310 } else if (gran == 1000000000) { 302 } else if (gran == NSEC_PER_SEC) {
311 t.tv_nsec = 0; 303 t.tv_nsec = 0;
312 } else { 304 } else if (gran > 1 && gran < NSEC_PER_SEC) {
313 t.tv_nsec -= t.tv_nsec % gran; 305 t.tv_nsec -= t.tv_nsec % gran;
306 } else {
307 WARN(1, "illegal file time granularity: %u", gran);
314 } 308 }
315 return t; 309 return t;
316} 310}
@@ -550,7 +544,7 @@ EXPORT_SYMBOL(__usecs_to_jiffies);
550 * value to a scaled second value. 544 * value to a scaled second value.
551 */ 545 */
552static unsigned long 546static unsigned long
553__timespec_to_jiffies(unsigned long sec, long nsec) 547__timespec64_to_jiffies(u64 sec, long nsec)
554{ 548{
555 nsec = nsec + TICK_NSEC - 1; 549 nsec = nsec + TICK_NSEC - 1;
556 550
@@ -558,22 +552,27 @@ __timespec_to_jiffies(unsigned long sec, long nsec)
558 sec = MAX_SEC_IN_JIFFIES; 552 sec = MAX_SEC_IN_JIFFIES;
559 nsec = 0; 553 nsec = 0;
560 } 554 }
561 return (((u64)sec * SEC_CONVERSION) + 555 return ((sec * SEC_CONVERSION) +
562 (((u64)nsec * NSEC_CONVERSION) >> 556 (((u64)nsec * NSEC_CONVERSION) >>
563 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; 557 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
564 558
565} 559}
566 560
567unsigned long 561static unsigned long
568timespec_to_jiffies(const struct timespec *value) 562__timespec_to_jiffies(unsigned long sec, long nsec)
569{ 563{
570 return __timespec_to_jiffies(value->tv_sec, value->tv_nsec); 564 return __timespec64_to_jiffies((u64)sec, nsec);
571} 565}
572 566
573EXPORT_SYMBOL(timespec_to_jiffies); 567unsigned long
568timespec64_to_jiffies(const struct timespec64 *value)
569{
570 return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec);
571}
572EXPORT_SYMBOL(timespec64_to_jiffies);
574 573
575void 574void
576jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) 575jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
577{ 576{
578 /* 577 /*
579 * Convert jiffies to nanoseconds and separate with 578 * Convert jiffies to nanoseconds and separate with
@@ -584,7 +583,7 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
584 NSEC_PER_SEC, &rem); 583 NSEC_PER_SEC, &rem);
585 value->tv_nsec = rem; 584 value->tv_nsec = rem;
586} 585}
587EXPORT_SYMBOL(jiffies_to_timespec); 586EXPORT_SYMBOL(jiffies_to_timespec64);
588 587
589/* 588/*
590 * We could use a similar algorithm to timespec_to_jiffies (with a 589 * We could use a similar algorithm to timespec_to_jiffies (with a
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index bca3667a2de1..f6ee2e6b6f5d 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -911,6 +911,7 @@ int do_settimeofday64(const struct timespec64 *ts)
911 struct timekeeper *tk = &tk_core.timekeeper; 911 struct timekeeper *tk = &tk_core.timekeeper;
912 struct timespec64 ts_delta, xt; 912 struct timespec64 ts_delta, xt;
913 unsigned long flags; 913 unsigned long flags;
914 int ret = 0;
914 915
915 if (!timespec64_valid_strict(ts)) 916 if (!timespec64_valid_strict(ts))
916 return -EINVAL; 917 return -EINVAL;
@@ -924,10 +925,15 @@ int do_settimeofday64(const struct timespec64 *ts)
924 ts_delta.tv_sec = ts->tv_sec - xt.tv_sec; 925 ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
925 ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec; 926 ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
926 927
928 if (timespec64_compare(&tk->wall_to_monotonic, &ts_delta) > 0) {
929 ret = -EINVAL;
930 goto out;
931 }
932
927 tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta)); 933 tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
928 934
929 tk_set_xtime(tk, ts); 935 tk_set_xtime(tk, ts);
930 936out:
931 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); 937 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
932 938
933 write_seqcount_end(&tk_core.seq); 939 write_seqcount_end(&tk_core.seq);
@@ -936,7 +942,7 @@ int do_settimeofday64(const struct timespec64 *ts)
936 /* signal hrtimers about time change */ 942 /* signal hrtimers about time change */
937 clock_was_set(); 943 clock_was_set();
938 944
939 return 0; 945 return ret;
940} 946}
941EXPORT_SYMBOL(do_settimeofday64); 947EXPORT_SYMBOL(do_settimeofday64);
942 948
@@ -965,7 +971,8 @@ int timekeeping_inject_offset(struct timespec *ts)
965 971
966 /* Make sure the proposed value is valid */ 972 /* Make sure the proposed value is valid */
967 tmp = timespec64_add(tk_xtime(tk), ts64); 973 tmp = timespec64_add(tk_xtime(tk), ts64);
968 if (!timespec64_valid_strict(&tmp)) { 974 if (timespec64_compare(&tk->wall_to_monotonic, &ts64) > 0 ||
975 !timespec64_valid_strict(&tmp)) {
969 ret = -EINVAL; 976 ret = -EINVAL;
970 goto error; 977 goto error;
971 } 978 }
@@ -1874,7 +1881,7 @@ struct timespec __current_kernel_time(void)
1874 return timespec64_to_timespec(tk_xtime(tk)); 1881 return timespec64_to_timespec(tk_xtime(tk));
1875} 1882}
1876 1883
1877struct timespec current_kernel_time(void) 1884struct timespec64 current_kernel_time64(void)
1878{ 1885{
1879 struct timekeeper *tk = &tk_core.timekeeper; 1886 struct timekeeper *tk = &tk_core.timekeeper;
1880 struct timespec64 now; 1887 struct timespec64 now;
@@ -1886,9 +1893,9 @@ struct timespec current_kernel_time(void)
1886 now = tk_xtime(tk); 1893 now = tk_xtime(tk);
1887 } while (read_seqcount_retry(&tk_core.seq, seq)); 1894 } while (read_seqcount_retry(&tk_core.seq, seq));
1888 1895
1889 return timespec64_to_timespec(now); 1896 return now;
1890} 1897}
1891EXPORT_SYMBOL(current_kernel_time); 1898EXPORT_SYMBOL(current_kernel_time64);
1892 1899
1893struct timespec64 get_monotonic_coarse64(void) 1900struct timespec64 get_monotonic_coarse64(void)
1894{ 1901{
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index a4536e1e3e2a..129c96033e46 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -137,7 +137,7 @@ print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
137 (unsigned long long) ktime_to_ns(base->offset)); 137 (unsigned long long) ktime_to_ns(base->offset));
138#endif 138#endif
139 SEQ_printf(m, "active timers:\n"); 139 SEQ_printf(m, "active timers:\n");
140 print_active_timers(m, base, now); 140 print_active_timers(m, base, now + ktime_to_ns(base->offset));
141} 141}
142 142
143static void print_cpu(struct seq_file *m, int cpu, u64 now) 143static void print_cpu(struct seq_file *m, int cpu, u64 now)