Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
"Rather large, but nothing exiting:

- new range check for settimeofday() to prevent that boot time
becomes negative.
- fix for file time rounding
- a few simplifications of the hrtimer code
- fix for the proc/timerlist code so the output of clock realtime
timers is accurate
- more y2038 work
- tree wide conversion of clockevent drivers to the new callbacks"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (88 commits)
hrtimer: Handle failure of tick_init_highres() gracefully
hrtimer: Unconfuse switch_hrtimer_base() a bit
hrtimer: Simplify get_target_base() by returning current base
hrtimer: Drop return code of hrtimer_switch_to_hres()
time: Introduce timespec64_to_jiffies()/jiffies_to_timespec64()
time: Introduce current_kernel_time64()
time: Introduce struct itimerspec64
time: Add the common weak version of update_persistent_clock()
time: Always make sure wall_to_monotonic isn't positive
time: Fix nanosecond file time rounding in timespec_trunc()
timer_list: Add the base offset so remaining nsecs are accurate for non monotonic timers
cris/time: Migrate to new 'set-state' interface
kernel: broadcast-hrtimer: Migrate to new 'set-state' interface
xtensa/time: Migrate to new 'set-state' interface
unicore/time: Migrate to new 'set-state' interface
um/time: Migrate to new 'set-state' interface
sparc/time: Migrate to new 'set-state' interface
sh/localtimer: Migrate to new 'set-state' interface
score/time: Migrate to new 'set-state' interface
s390/time: Migrate to new 'set-state' interface
...

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