diff options
| author | Viresh Kumar <viresh.kumar@linaro.org> | 2015-06-18 06:54:52 -0400 |
|---|---|---|
| committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2015-08-10 05:40:49 -0400 |
| commit | 8ff8fc13bdd4f1474720669042fccfbf304638f1 (patch) | |
| tree | ab78e0696c23c32df200b322eea77544bb9ef554 /drivers/clocksource | |
| parent | 7486f5ad27f6833397d55972878e7d73e84bede2 (diff) | |
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>
Diffstat (limited to 'drivers/clocksource')
| -rw-r--r-- | drivers/clocksource/timer-u300.c | 155 |
1 files changed, 77 insertions, 78 deletions
diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c index 5dcf756970e7..1744b243898a 100644 --- a/drivers/clocksource/timer-u300.c +++ b/drivers/clocksource/timer-u300.c | |||
| @@ -187,85 +187,82 @@ struct u300_clockevent_data { | |||
| 187 | unsigned ticks_per_jiffy; | 187 | unsigned ticks_per_jiffy; |
| 188 | }; | 188 | }; |
| 189 | 189 | ||
| 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 | 202 | * If we have oneshot timer active, the oneshot scheduling function |
| 192 | * have oneshot timer active, the oneshot scheduling function | ||
| 193 | * u300_set_next_event() is called immediately after. | 203 | * u300_set_next_event() is called immediately after. |
| 194 | */ | 204 | */ |
| 195 | static void u300_set_mode(enum clock_event_mode mode, | 205 | static int u300_set_oneshot(struct clock_event_device *evt) |
| 196 | struct clock_event_device *evt) | 206 | { |
| 207 | /* Just return; here? */ | ||
| 208 | /* | ||
| 209 | * The actual event will be programmed by the next event hook, | ||
| 210 | * so we just set a dummy value somewhere at the end of the | ||
| 211 | * universe here. | ||
| 212 | */ | ||
| 213 | /* Disable interrupts on GPT1 */ | ||
| 214 | writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, | ||
| 215 | u300_timer_base + U300_TIMER_APP_GPT1IE); | ||
| 216 | /* Disable GP1 while we're reprogramming it. */ | ||
| 217 | writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, | ||
| 218 | u300_timer_base + U300_TIMER_APP_DGPT1); | ||
| 219 | /* | ||
| 220 | * Expire far in the future, u300_set_next_event() will be | ||
| 221 | * called soon... | ||
| 222 | */ | ||
| 223 | writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); | ||
| 224 | /* We run one shot per tick here! */ | ||
| 225 | writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, | ||
| 226 | u300_timer_base + U300_TIMER_APP_SGPT1M); | ||
| 227 | /* Enable interrupts for this timer */ | ||
| 228 | writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, | ||
| 229 | u300_timer_base + U300_TIMER_APP_GPT1IE); | ||
| 230 | /* Enable timer */ | ||
| 231 | writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, | ||
| 232 | u300_timer_base + U300_TIMER_APP_EGPT1); | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | static int u300_set_periodic(struct clock_event_device *evt) | ||
| 197 | { | 237 | { |
| 198 | struct u300_clockevent_data *cevdata = | 238 | struct u300_clockevent_data *cevdata = |
| 199 | container_of(evt, struct u300_clockevent_data, cevd); | 239 | container_of(evt, struct u300_clockevent_data, cevd); |
| 200 | 240 | ||
| 201 | switch (mode) { | 241 | /* Disable interrupts on GPT1 */ |
| 202 | case CLOCK_EVT_MODE_PERIODIC: | 242 | writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, |
| 203 | /* Disable interrupts on GPT1 */ | 243 | u300_timer_base + U300_TIMER_APP_GPT1IE); |
| 204 | writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, | 244 | /* Disable GP1 while we're reprogramming it. */ |
| 205 | u300_timer_base + U300_TIMER_APP_GPT1IE); | 245 | writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, |
| 206 | /* Disable GP1 while we're reprogramming it. */ | 246 | u300_timer_base + U300_TIMER_APP_DGPT1); |
| 207 | writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, | 247 | /* |
| 208 | u300_timer_base + U300_TIMER_APP_DGPT1); | 248 | * Set the periodic mode to a certain number of ticks per |
| 209 | /* | 249 | * jiffy. |
| 210 | * Set the periodic mode to a certain number of ticks per | 250 | */ |
| 211 | * jiffy. | 251 | writel(cevdata->ticks_per_jiffy, |
| 212 | */ | 252 | u300_timer_base + U300_TIMER_APP_GPT1TC); |
| 213 | writel(cevdata->ticks_per_jiffy, | 253 | /* |
| 214 | u300_timer_base + U300_TIMER_APP_GPT1TC); | 254 | * Set continuous mode, so the timer keeps triggering |
| 215 | /* | 255 | * interrupts. |
| 216 | * Set continuous mode, so the timer keeps triggering | 256 | */ |
| 217 | * interrupts. | 257 | writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, |
| 218 | */ | 258 | u300_timer_base + U300_TIMER_APP_SGPT1M); |
| 219 | writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, | 259 | /* Enable timer interrupts */ |
| 220 | u300_timer_base + U300_TIMER_APP_SGPT1M); | 260 | writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, |
| 221 | /* Enable timer interrupts */ | 261 | u300_timer_base + U300_TIMER_APP_GPT1IE); |
| 222 | writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, | 262 | /* Then enable the OS timer again */ |
| 223 | u300_timer_base + U300_TIMER_APP_GPT1IE); | 263 | writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, |
| 224 | /* Then enable the OS timer again */ | 264 | u300_timer_base + U300_TIMER_APP_EGPT1); |
| 225 | writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, | 265 | return 0; |
| 226 | u300_timer_base + U300_TIMER_APP_EGPT1); | ||
| 227 | break; | ||
| 228 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 229 | /* Just break; here? */ | ||
| 230 | /* | ||
| 231 | * The actual event will be programmed by the next event hook, | ||
| 232 | * so we just set a dummy value somewhere at the end of the | ||
| 233 | * universe here. | ||
| 234 | */ | ||
| 235 | /* Disable interrupts on GPT1 */ | ||
| 236 | writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, | ||
| 237 | u300_timer_base + U300_TIMER_APP_GPT1IE); | ||
| 238 | /* Disable GP1 while we're reprogramming it. */ | ||
| 239 | writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, | ||
| 240 | u300_timer_base + U300_TIMER_APP_DGPT1); | ||
| 241 | /* | ||
| 242 | * Expire far in the future, u300_set_next_event() will be | ||
| 243 | * called soon... | ||
| 244 | */ | ||
| 245 | writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); | ||
| 246 | /* We run one shot per tick here! */ | ||
| 247 | writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, | ||
| 248 | u300_timer_base + U300_TIMER_APP_SGPT1M); | ||
| 249 | /* Enable interrupts for this timer */ | ||
| 250 | writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, | ||
| 251 | u300_timer_base + U300_TIMER_APP_GPT1IE); | ||
| 252 | /* Enable timer */ | ||
| 253 | writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, | ||
| 254 | u300_timer_base + U300_TIMER_APP_EGPT1); | ||
| 255 | break; | ||
| 256 | case CLOCK_EVT_MODE_UNUSED: | ||
| 257 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 258 | /* Disable interrupts on GP1 */ | ||
| 259 | writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, | ||
| 260 | u300_timer_base + U300_TIMER_APP_GPT1IE); | ||
| 261 | /* Disable GP1 */ | ||
| 262 | writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, | ||
| 263 | u300_timer_base + U300_TIMER_APP_DGPT1); | ||
| 264 | break; | ||
| 265 | case CLOCK_EVT_MODE_RESUME: | ||
| 266 | /* Ignore this call */ | ||
| 267 | break; | ||
| 268 | } | ||
| 269 | } | 266 | } |
| 270 | 267 | ||
| 271 | /* | 268 | /* |
| @@ -309,13 +306,15 @@ static int u300_set_next_event(unsigned long cycles, | |||
| 309 | static struct u300_clockevent_data u300_clockevent_data = { | 306 | static struct u300_clockevent_data u300_clockevent_data = { |
| 310 | /* Use general purpose timer 1 as clock event */ | 307 | /* Use general purpose timer 1 as clock event */ |
| 311 | .cevd = { | 308 | .cevd = { |
| 312 | .name = "GPT1", | 309 | .name = "GPT1", |
| 313 | /* Reasonably fast and accurate clock event */ | 310 | /* Reasonably fast and accurate clock event */ |
| 314 | .rating = 300, | 311 | .rating = 300, |
| 315 | .features = CLOCK_EVT_FEAT_PERIODIC | | 312 | .features = CLOCK_EVT_FEAT_PERIODIC | |
| 316 | CLOCK_EVT_FEAT_ONESHOT, | 313 | CLOCK_EVT_FEAT_ONESHOT, |
| 317 | .set_next_event = u300_set_next_event, | 314 | .set_next_event = u300_set_next_event, |
| 318 | .set_mode = u300_set_mode, | 315 | .set_state_shutdown = u300_shutdown, |
| 316 | .set_state_periodic = u300_set_periodic, | ||
| 317 | .set_state_oneshot = u300_set_oneshot, | ||
| 319 | }, | 318 | }, |
| 320 | }; | 319 | }; |
| 321 | 320 | ||
