aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clocksource/samsung_pwm_timer.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index b3112dc293ba..ac60f8b8a5f7 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -207,17 +207,6 @@ static int samsung_set_next_event(unsigned long cycles,
207 return 0; 207 return 0;
208} 208}
209 209
210static void samsung_timer_resume(void)
211{
212 /* event timer restart */
213 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
214 samsung_time_start(pwm.event_id, true);
215
216 /* source timer restart */
217 samsung_time_setup(pwm.source_id, pwm.tcnt_max);
218 samsung_time_start(pwm.source_id, true);
219}
220
221static void samsung_set_mode(enum clock_event_mode mode, 210static void samsung_set_mode(enum clock_event_mode mode,
222 struct clock_event_device *evt) 211 struct clock_event_device *evt)
223{ 212{
@@ -234,20 +223,29 @@ static void samsung_set_mode(enum clock_event_mode mode,
234 223
235 case CLOCK_EVT_MODE_UNUSED: 224 case CLOCK_EVT_MODE_UNUSED:
236 case CLOCK_EVT_MODE_SHUTDOWN: 225 case CLOCK_EVT_MODE_SHUTDOWN:
237 break;
238
239 case CLOCK_EVT_MODE_RESUME: 226 case CLOCK_EVT_MODE_RESUME:
240 samsung_timer_resume();
241 break; 227 break;
242 } 228 }
243} 229}
244 230
231static void samsung_clockevent_resume(struct clock_event_device *cev)
232{
233 samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div);
234 samsung_timer_set_divisor(pwm.event_id, pwm.tdiv);
235
236 if (pwm.variant.has_tint_cstat) {
237 u32 mask = (1 << pwm.event_id);
238 writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT);
239 }
240}
241
245static struct clock_event_device time_event_device = { 242static struct clock_event_device time_event_device = {
246 .name = "samsung_event_timer", 243 .name = "samsung_event_timer",
247 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 244 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
248 .rating = 200, 245 .rating = 200,
249 .set_next_event = samsung_set_next_event, 246 .set_next_event = samsung_set_next_event,
250 .set_mode = samsung_set_mode, 247 .set_mode = samsung_set_mode,
248 .resume = samsung_clockevent_resume,
251}; 249};
252 250
253static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) 251static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
@@ -298,6 +296,20 @@ static void __init samsung_clockevent_init(void)
298 } 296 }
299} 297}
300 298
299static void samsung_clocksource_suspend(struct clocksource *cs)
300{
301 samsung_time_stop(pwm.source_id);
302}
303
304static void samsung_clocksource_resume(struct clocksource *cs)
305{
306 samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div);
307 samsung_timer_set_divisor(pwm.source_id, pwm.tdiv);
308
309 samsung_time_setup(pwm.source_id, pwm.tcnt_max);
310 samsung_time_start(pwm.source_id, true);
311}
312
301static cycle_t samsung_clocksource_read(struct clocksource *c) 313static cycle_t samsung_clocksource_read(struct clocksource *c)
302{ 314{
303 return ~readl_relaxed(pwm.source_reg); 315 return ~readl_relaxed(pwm.source_reg);
@@ -307,6 +319,8 @@ static struct clocksource samsung_clocksource = {
307 .name = "samsung_clocksource_timer", 319 .name = "samsung_clocksource_timer",
308 .rating = 250, 320 .rating = 250,
309 .read = samsung_clocksource_read, 321 .read = samsung_clocksource_read,
322 .suspend = samsung_clocksource_suspend,
323 .resume = samsung_clocksource_resume,
310 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 324 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
311}; 325};
312 326