diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-11-30 12:21:21 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-12-29 12:36:07 +0000 |
commit | 4808972a1cac08f8e8d65419ab56d27a9da3a922 (patch) | |
tree | 3d026b41bf42408ebd8205b976dc19f582e07a1e /arch/arm/mach-footbridge | |
parent | 6cefe92f2991c2bcd8f3a16faa9f4e3c91be48f2 (diff) |
ARM: footbridge: add one-shot mode for DC21285 timer
Add a one-shot mode for the DC21285 timer. This allows us to use the
NO_HZ modes on this platform.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-footbridge')
-rw-r--r-- | arch/arm/mach-footbridge/dc21285-timer.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 785e4199f9cd..2babdbcaa691 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -47,6 +47,16 @@ static struct clocksource cksrc_dc21285 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static int ckevt_dc21285_set_next_event(unsigned long delta, + struct clock_event_device *c) +{ + *CSR_TIMER1_CLR = 0; + *CSR_TIMER1_LOAD = delta; + *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; + + return 0; +} + static void ckevt_dc21285_set_mode(enum clock_event_mode mode, struct clock_event_device *c) { @@ -59,7 +69,9 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, TIMER_CNTL_DIV16; break; - default: + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: *CSR_TIMER1_CNTL = 0; break; } @@ -67,9 +79,11 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, static struct clock_event_device ckevt_dc21285 = { .name = "dc21285_timer1", - .features = CLOCK_EVT_FEAT_PERIODIC, + .features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT, .rating = 200, .irq = IRQ_TIMER1, + .set_next_event = ckevt_dc21285_set_next_event, .set_mode = ckevt_dc21285_set_mode, }; @@ -79,6 +93,10 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) *CSR_TIMER1_CLR = 0; + /* Stop the timer if in one-shot mode */ + if (ce->mode == CLOCK_EVT_MODE_ONESHOT) + *CSR_TIMER1_CNTL = 0; + ce->event_handler(ce); return IRQ_HANDLED; |