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

clockevents/drivers/u300: Migrate to new 'set-state' interface

Migrate u300 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Viresh Kumar and committed by
Daniel Lezcano
8ff8fc13 7486f5ad

+77 -78
+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