mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 23:29:46 +00:00
Merge branch 'ARM/clkevt/set-state-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux into next/cleanup
Merge "ARM: clockevents: Migrate to 'set-state' callbacks" from Viresh Kumar: This series migrates ARM clockevent drivers (present in arch/arm/ directory), to the new set-state interface. This would enable these drivers to use new states (like: ONESHOT_STOPPED, etc.) of a clockevent device (if required), as the set-mode interface is marked obsolete now and wouldn't be expanded to handle new states. * 'ARM/clkevt/set-state-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux: ARM/orion/time: Migrate to new 'set-state' interface ARM/iop/time: Migrate to new 'set-state' interface ARM/w90x900/time: Migrate to new 'set-state' interface ARM/SPEAr/time: Migrate to new 'set-state' interface ARM/omap2/timer: Migrate to new 'set-state' interface ARM/omap1/timer32: Migrate to new 'set-state' interface ARM/omap1/time: Migrate to new 'set-state' interface ARM/netx/time: Migrate to new 'set-state' interface ARM/mmp/time: Migrate to new 'set-state' interface ARM/lpc32xx/timer: Migrate to new 'set-state' interface ARM/ks8695/time: Migrate to new 'set-state' interface ARM/ixp4xx/timer: Migrate to new 'set-state' interface ARM/imx/epit: Migrate to new 'set-state' interface ARM/gemini/time: Migrate to new 'set-state' interface ARM/dc21285-timer: Migrate to new 'set-state' interface ARM/davinci/time: Migrate to new 'set-state' interface ARM/cns3xxx/timer: Migrate to new 'set-state' interface ARM/smp_twd: Migrate to new 'set-state' interface Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
52e43a11ae
@ -36,29 +36,30 @@ static DEFINE_PER_CPU(bool, percpu_setup_called);
|
||||
static struct clock_event_device __percpu *twd_evt;
|
||||
static int twd_ppi;
|
||||
|
||||
static void twd_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
static int twd_shutdown(struct clock_event_device *clk)
|
||||
{
|
||||
unsigned long ctrl;
|
||||
writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
|
||||
| TWD_TIMER_CONTROL_PERIODIC;
|
||||
writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
|
||||
twd_base + TWD_TIMER_LOAD);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* period set, and timer enabled in 'next_event' hook */
|
||||
ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
default:
|
||||
ctrl = 0;
|
||||
}
|
||||
static int twd_set_oneshot(struct clock_event_device *clk)
|
||||
{
|
||||
/* period set, and timer enabled in 'next_event' hook */
|
||||
writel_relaxed(TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT,
|
||||
twd_base + TWD_TIMER_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int twd_set_periodic(struct clock_event_device *clk)
|
||||
{
|
||||
unsigned long ctrl = TWD_TIMER_CONTROL_ENABLE |
|
||||
TWD_TIMER_CONTROL_IT_ENABLE |
|
||||
TWD_TIMER_CONTROL_PERIODIC;
|
||||
|
||||
writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
|
||||
twd_base + TWD_TIMER_LOAD);
|
||||
writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int twd_set_next_event(unsigned long evt,
|
||||
@ -94,7 +95,7 @@ static void twd_timer_stop(void)
|
||||
{
|
||||
struct clock_event_device *clk = raw_cpu_ptr(twd_evt);
|
||||
|
||||
twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
|
||||
twd_shutdown(clk);
|
||||
disable_percpu_irq(clk->irq);
|
||||
}
|
||||
|
||||
@ -296,7 +297,10 @@ static void twd_timer_setup(void)
|
||||
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_C3STOP;
|
||||
clk->rating = 350;
|
||||
clk->set_mode = twd_set_mode;
|
||||
clk->set_state_shutdown = twd_shutdown;
|
||||
clk->set_state_periodic = twd_set_periodic;
|
||||
clk->set_state_oneshot = twd_set_oneshot;
|
||||
clk->tick_resume = twd_shutdown;
|
||||
clk->set_next_event = twd_set_next_event;
|
||||
clk->irq = twd_ppi;
|
||||
clk->cpumask = cpumask_of(cpu);
|
||||
|
@ -113,30 +113,33 @@ void cns3xxx_power_off(void)
|
||||
*/
|
||||
static void __iomem *cns3xxx_tmr1;
|
||||
|
||||
static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
static int cns3xxx_shutdown(struct clock_event_device *clk)
|
||||
{
|
||||
writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cns3xxx_set_oneshot(struct clock_event_device *clk)
|
||||
{
|
||||
unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
|
||||
/* period set, and timer enabled in 'next_event' hook */
|
||||
ctrl |= (1 << 2) | (1 << 9);
|
||||
writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cns3xxx_set_periodic(struct clock_event_device *clk)
|
||||
{
|
||||
unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
int pclk = cns3xxx_cpu_clock() / 8;
|
||||
int reload;
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
reload = pclk * 20 / (3 * HZ) * 0x25000;
|
||||
writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
|
||||
ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* period set, and timer enabled in 'next_event' hook */
|
||||
ctrl |= (1 << 2) | (1 << 9);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
default:
|
||||
ctrl = 0;
|
||||
}
|
||||
|
||||
reload = pclk * 20 / (3 * HZ) * 0x25000;
|
||||
writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
|
||||
ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
|
||||
writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cns3xxx_timer_set_next_event(unsigned long evt,
|
||||
@ -151,12 +154,16 @@ static int cns3xxx_timer_set_next_event(unsigned long evt,
|
||||
}
|
||||
|
||||
static struct clock_event_device cns3xxx_tmr1_clockevent = {
|
||||
.name = "cns3xxx timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = cns3xxx_timer_set_mode,
|
||||
.set_next_event = cns3xxx_timer_set_next_event,
|
||||
.rating = 350,
|
||||
.cpumask = cpu_all_mask,
|
||||
.name = "cns3xxx timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = cns3xxx_shutdown,
|
||||
.set_state_periodic = cns3xxx_set_periodic,
|
||||
.set_state_oneshot = cns3xxx_set_oneshot,
|
||||
.tick_resume = cns3xxx_shutdown,
|
||||
.set_next_event = cns3xxx_timer_set_next_event,
|
||||
.rating = 350,
|
||||
.cpumask = cpu_all_mask,
|
||||
};
|
||||
|
||||
static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
|
||||
|
@ -303,36 +303,42 @@ static int davinci_set_next_event(unsigned long cycles,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void davinci_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int davinci_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_s *t = &timers[TID_CLOCKEVENT];
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
t->period = davinci_clock_tick_rate / (HZ);
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_PERIODIC;
|
||||
timer32_config(t);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_ONESHOT;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_DISABLED;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_s *t = &timers[TID_CLOCKEVENT];
|
||||
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_ONESHOT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_s *t = &timers[TID_CLOCKEVENT];
|
||||
|
||||
t->period = davinci_clock_tick_rate / (HZ);
|
||||
t->opts &= ~TIMER_OPTS_STATE_MASK;
|
||||
t->opts |= TIMER_OPTS_PERIODIC;
|
||||
timer32_config(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_davinci = {
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = davinci_set_next_event,
|
||||
.set_mode = davinci_set_mode,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = davinci_set_next_event,
|
||||
.set_state_shutdown = davinci_shutdown,
|
||||
.set_state_periodic = davinci_set_periodic,
|
||||
.set_state_oneshot = davinci_set_oneshot,
|
||||
};
|
||||
|
||||
|
||||
|
@ -57,34 +57,32 @@ static int ckevt_dc21285_set_next_event(unsigned long delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *c)
|
||||
static int ckevt_dc21285_shutdown(struct clock_event_device *c)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
*CSR_TIMER1_CLR = 0;
|
||||
*CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
|
||||
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
|
||||
TIMER_CNTL_DIV16;
|
||||
break;
|
||||
*CSR_TIMER1_CNTL = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
*CSR_TIMER1_CNTL = 0;
|
||||
break;
|
||||
}
|
||||
static int ckevt_dc21285_set_periodic(struct clock_event_device *c)
|
||||
{
|
||||
*CSR_TIMER1_CLR = 0;
|
||||
*CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
|
||||
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
|
||||
TIMER_CNTL_DIV16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device ckevt_dc21285 = {
|
||||
.name = "dc21285_timer1",
|
||||
.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,
|
||||
.name = "dc21285_timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.irq = IRQ_TIMER1,
|
||||
.set_next_event = ckevt_dc21285_set_next_event,
|
||||
.set_state_shutdown = ckevt_dc21285_shutdown,
|
||||
.set_state_periodic = ckevt_dc21285_set_periodic,
|
||||
.set_state_oneshot = ckevt_dc21285_shutdown,
|
||||
.tick_resume = ckevt_dc21285_set_periodic,
|
||||
};
|
||||
|
||||
static irqreturn_t timer1_interrupt(int irq, void *dev_id)
|
||||
@ -94,7 +92,7 @@ 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)
|
||||
if (clockevent_state_oneshot(ce))
|
||||
*CSR_TIMER1_CNTL = 0;
|
||||
|
||||
ce->event_handler(ce);
|
||||
|
@ -59,49 +59,48 @@ static int gemini_timer_set_next_event(unsigned long cycles,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gemini_timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int gemini_timer_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
u32 cr;
|
||||
|
||||
/*
|
||||
* Disable also for oneshot: the set_next() call will arm the timer
|
||||
* instead.
|
||||
*/
|
||||
cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
cr &= ~TIMER_2_CR_ENABLE;
|
||||
cr &= ~TIMER_2_CR_INT;
|
||||
writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gemini_timer_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
|
||||
u32 cr;
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
/* Start the timer */
|
||||
writel(period,
|
||||
TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
|
||||
writel(period,
|
||||
TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
|
||||
cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
cr |= TIMER_2_CR_ENABLE;
|
||||
cr |= TIMER_2_CR_INT;
|
||||
writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
/*
|
||||
* Disable also for oneshot: the set_next() call will
|
||||
* arm the timer instead.
|
||||
*/
|
||||
cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
cr &= ~TIMER_2_CR_ENABLE;
|
||||
cr &= ~TIMER_2_CR_INT;
|
||||
writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Start the timer */
|
||||
writel(period, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
|
||||
writel(period, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
|
||||
cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
cr |= TIMER_2_CR_ENABLE;
|
||||
cr |= TIMER_2_CR_INT;
|
||||
writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use TIMER2 as clock event */
|
||||
static struct clock_event_device gemini_clockevent = {
|
||||
.name = "TIMER2",
|
||||
.rating = 300, /* Reasonably fast and accurate clock event */
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = gemini_timer_set_next_event,
|
||||
.set_mode = gemini_timer_set_mode,
|
||||
.name = "TIMER2",
|
||||
/* Reasonably fast and accurate clock event */
|
||||
.rating = 300,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = gemini_timer_set_next_event,
|
||||
.set_state_shutdown = gemini_timer_shutdown,
|
||||
.set_state_periodic = gemini_timer_set_periodic,
|
||||
.set_state_oneshot = gemini_timer_shutdown,
|
||||
.tick_resume = gemini_timer_shutdown,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -57,7 +57,6 @@
|
||||
#include "hardware.h"
|
||||
|
||||
static struct clock_event_device clockevent_epit;
|
||||
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
|
||||
|
||||
static void __iomem *timer_base;
|
||||
|
||||
@ -106,8 +105,8 @@ static int epit_set_next_event(unsigned long evt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void epit_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
/* Left event sources disabled, no more interrupts appear */
|
||||
static int epit_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@ -120,39 +119,41 @@ static void epit_set_mode(enum clock_event_mode mode,
|
||||
/* Disable interrupt in GPT module */
|
||||
epit_irq_disable();
|
||||
|
||||
if (mode != clockevent_mode) {
|
||||
/* Set event time into far-far future */
|
||||
/* Clear pending interrupt */
|
||||
epit_irq_acknowledge();
|
||||
|
||||
/* Clear pending interrupt */
|
||||
epit_irq_acknowledge();
|
||||
}
|
||||
|
||||
/* Remember timer mode */
|
||||
clockevent_mode = mode;
|
||||
local_irq_restore(flags);
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
printk(KERN_ERR "epit_set_mode: Periodic mode is not "
|
||||
"supported for i.MX EPIT\n");
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int epit_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* The timer interrupt generation is disabled at least
|
||||
* for enough time to call epit_set_next_event()
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Disable interrupt in GPT module */
|
||||
epit_irq_disable();
|
||||
|
||||
/* Clear pending interrupt, only while switching mode */
|
||||
if (!clockevent_state_oneshot(evt))
|
||||
epit_irq_acknowledge();
|
||||
|
||||
/*
|
||||
* Do not put overhead of interrupt enable/disable into
|
||||
* epit_set_next_event(), the core has about 4 minutes
|
||||
* to call epit_set_next_event() or shutdown clock after
|
||||
* mode switching
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
epit_irq_enable();
|
||||
local_irq_restore(flags);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
/* Left event sources disabled, no more interrupts appear */
|
||||
break;
|
||||
}
|
||||
epit_irq_enable();
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -176,11 +177,13 @@ static struct irqaction epit_timer_irq = {
|
||||
};
|
||||
|
||||
static struct clock_event_device clockevent_epit = {
|
||||
.name = "epit",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = epit_set_mode,
|
||||
.set_next_event = epit_set_next_event,
|
||||
.rating = 200,
|
||||
.name = "epit",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = epit_shutdown,
|
||||
.tick_resume = epit_shutdown,
|
||||
.set_state_oneshot = epit_set_oneshot,
|
||||
.set_next_event = epit_set_next_event,
|
||||
.rating = 200,
|
||||
};
|
||||
|
||||
static int __init epit_clockevent_init(struct clk *timer_clk)
|
||||
|
@ -521,43 +521,55 @@ static int ixp4xx_set_next_event(unsigned long evt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ixp4xx_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int ixp4xx_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
|
||||
unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
|
||||
opts = IXP4XX_OST_ENABLE;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* period set by 'set next_event' */
|
||||
osrt = 0;
|
||||
opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
opts &= ~IXP4XX_OST_ENABLE;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
opts |= IXP4XX_OST_ENABLE;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
default:
|
||||
osrt = opts = 0;
|
||||
break;
|
||||
}
|
||||
opts &= ~IXP4XX_OST_ENABLE;
|
||||
*IXP4XX_OSRT1 = osrt | opts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ixp4xx_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
|
||||
unsigned long osrt = 0;
|
||||
|
||||
/* period set by 'set next_event' */
|
||||
*IXP4XX_OSRT1 = osrt | opts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ixp4xx_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long opts = IXP4XX_OST_ENABLE;
|
||||
unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
|
||||
|
||||
*IXP4XX_OSRT1 = osrt | opts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ixp4xx_resume(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
|
||||
unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
|
||||
|
||||
opts |= IXP4XX_OST_ENABLE;
|
||||
*IXP4XX_OSRT1 = osrt | opts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_ixp4xx = {
|
||||
.name = "ixp4xx timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.set_mode = ixp4xx_set_mode,
|
||||
.set_next_event = ixp4xx_set_next_event,
|
||||
.name = "ixp4xx timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.set_state_shutdown = ixp4xx_shutdown,
|
||||
.set_state_periodic = ixp4xx_set_periodic,
|
||||
.set_state_oneshot = ixp4xx_set_oneshot,
|
||||
.tick_resume = ixp4xx_resume,
|
||||
.set_next_event = ixp4xx_set_next_event,
|
||||
};
|
||||
|
||||
static void __init ixp4xx_clockevent_init(void)
|
||||
|
@ -54,28 +54,25 @@
|
||||
/* Timer0 Timeout Counter Register */
|
||||
#define T0TC_WATCHDOG (0xff) /* Enable watchdog mode */
|
||||
|
||||
static void ks8695_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int ks8695_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 rate = DIV_ROUND_CLOSEST(KS8695_CLOCK_RATE, HZ);
|
||||
u32 half = DIV_ROUND_CLOSEST(rate, 2);
|
||||
u32 tmcon;
|
||||
|
||||
if (mode == CLOCK_EVT_FEAT_PERIODIC) {
|
||||
u32 rate = DIV_ROUND_CLOSEST(KS8695_CLOCK_RATE, HZ);
|
||||
u32 half = DIV_ROUND_CLOSEST(rate, 2);
|
||||
/* Disable timer 1 */
|
||||
tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
|
||||
tmcon &= ~TMCON_T1EN;
|
||||
writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
|
||||
|
||||
/* Disable timer 1 */
|
||||
tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
|
||||
tmcon &= ~TMCON_T1EN;
|
||||
writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
|
||||
/* Both registers need to count down */
|
||||
writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
|
||||
writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
|
||||
|
||||
/* Both registers need to count down */
|
||||
writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
|
||||
writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
|
||||
|
||||
/* Re-enable timer1 */
|
||||
tmcon |= TMCON_T1EN;
|
||||
writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
|
||||
}
|
||||
/* Re-enable timer1 */
|
||||
tmcon |= TMCON_T1EN;
|
||||
writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ks8695_set_next_event(unsigned long cycles,
|
||||
@ -102,11 +99,13 @@ static int ks8695_set_next_event(unsigned long cycles,
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_ks8695 = {
|
||||
.name = "ks8695_t1tc",
|
||||
.rating = 300, /* Reasonably fast and accurate clock event */
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
|
||||
.set_next_event = ks8695_set_next_event,
|
||||
.set_mode = ks8695_set_mode,
|
||||
.name = "ks8695_t1tc",
|
||||
/* Reasonably fast and accurate clock event */
|
||||
.rating = 300,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_PERIODIC,
|
||||
.set_next_event = ks8695_set_next_event,
|
||||
.set_state_periodic = ks8695_set_periodic,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -43,36 +43,24 @@ static int lpc32xx_clkevt_next_event(unsigned long delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *dev)
|
||||
static int lpc32xx_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
/*
|
||||
* Disable the timer. When using oneshot, we must also
|
||||
* disable the timer to wait for the first call to
|
||||
* set_next_event().
|
||||
*/
|
||||
__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Disable the timer. When using oneshot, we must also
|
||||
* disable the timer to wait for the first call to
|
||||
* set_next_event().
|
||||
*/
|
||||
__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device lpc32xx_clkevt = {
|
||||
.name = "lpc32xx_clkevt",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = lpc32xx_clkevt_next_event,
|
||||
.set_mode = lpc32xx_clkevt_mode,
|
||||
.name = "lpc32xx_clkevt",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = lpc32xx_clkevt_next_event,
|
||||
.set_state_shutdown = lpc32xx_shutdown,
|
||||
.set_state_oneshot = lpc32xx_shutdown,
|
||||
};
|
||||
|
||||
static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
|
||||
|
@ -124,32 +124,25 @@ static int timer_set_next_event(unsigned long delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *dev)
|
||||
static int timer_set_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
/* disable the matching interrupt */
|
||||
__raw_writel(0x00, mmp_timer_base + TMR_IER(0));
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
break;
|
||||
}
|
||||
/* disable the matching interrupt */
|
||||
__raw_writel(0x00, mmp_timer_base + TMR_IER(0));
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device ckevt = {
|
||||
.name = "clockevent",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.set_next_event = timer_set_next_event,
|
||||
.set_mode = timer_set_mode,
|
||||
.name = "clockevent",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.set_next_event = timer_set_next_event,
|
||||
.set_state_shutdown = timer_set_shutdown,
|
||||
.set_state_oneshot = timer_set_shutdown,
|
||||
};
|
||||
|
||||
static cycle_t clksrc_read(struct clocksource *cs)
|
||||
|
@ -34,40 +34,40 @@
|
||||
#define TIMER_CLOCKEVENT 0
|
||||
#define TIMER_CLOCKSOURCE 1
|
||||
|
||||
static void netx_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
static inline void timer_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmode;
|
||||
|
||||
/* disable timer */
|
||||
writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
writel(NETX_LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
|
||||
tmode = NETX_GPIO_COUNTER_CTRL_RST_EN |
|
||||
NETX_GPIO_COUNTER_CTRL_IRQ_EN |
|
||||
NETX_GPIO_COUNTER_CTRL_RUN;
|
||||
break;
|
||||
static int netx_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
timer_shutdown(evt);
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
writel(0, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
|
||||
tmode = NETX_GPIO_COUNTER_CTRL_IRQ_EN |
|
||||
NETX_GPIO_COUNTER_CTRL_RUN;
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
WARN(1, "%s: unhandled mode %d\n", __func__, mode);
|
||||
/* fall through */
|
||||
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
tmode = 0;
|
||||
break;
|
||||
}
|
||||
static int netx_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmode = NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN;
|
||||
|
||||
timer_shutdown(evt);
|
||||
writel(0, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
|
||||
writel(tmode, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netx_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmode = NETX_GPIO_COUNTER_CTRL_RST_EN |
|
||||
NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN;
|
||||
|
||||
timer_shutdown(evt);
|
||||
writel(NETX_LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
|
||||
writel(tmode, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netx_set_next_event(unsigned long evt,
|
||||
@ -81,7 +81,10 @@ static struct clock_event_device netx_clockevent = {
|
||||
.name = "netx-timer" __stringify(TIMER_CLOCKEVENT),
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = netx_set_next_event,
|
||||
.set_mode = netx_set_mode,
|
||||
.set_state_shutdown = netx_shutdown,
|
||||
.set_state_periodic = netx_set_periodic,
|
||||
.set_state_oneshot = netx_set_oneshot,
|
||||
.tick_resume = netx_shutdown,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -124,29 +124,26 @@ static int omap_mpu_set_next_event(unsigned long cycles,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_mpu_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int omap_mpu_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
omap_mpu_set_autoreset(0);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
omap_mpu_timer_stop(0);
|
||||
omap_mpu_remove_autoreset(0);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
omap_mpu_timer_stop(0);
|
||||
omap_mpu_remove_autoreset(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_mpu_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
omap_mpu_set_autoreset(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_mpu_timer1 = {
|
||||
.name = "mpu_timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = omap_mpu_set_next_event,
|
||||
.set_mode = omap_mpu_set_mode,
|
||||
.name = "mpu_timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = omap_mpu_set_next_event,
|
||||
.set_state_periodic = omap_mpu_set_periodic,
|
||||
.set_state_oneshot = omap_mpu_set_oneshot,
|
||||
};
|
||||
|
||||
static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
|
||||
|
@ -114,29 +114,28 @@ static int omap_32k_timer_set_next_event(unsigned long delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_32k_timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int omap_32k_timer_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
omap_32k_timer_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
static int omap_32k_timer_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
omap_32k_timer_stop();
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_32k_timer = {
|
||||
.name = "32k-timer",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = omap_32k_timer_set_next_event,
|
||||
.set_mode = omap_32k_timer_set_mode,
|
||||
.name = "32k-timer",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = omap_32k_timer_set_next_event,
|
||||
.set_state_shutdown = omap_32k_timer_shutdown,
|
||||
.set_state_periodic = omap_32k_timer_set_periodic,
|
||||
.set_state_oneshot = omap_32k_timer_shutdown,
|
||||
.tick_resume = omap_32k_timer_shutdown,
|
||||
};
|
||||
|
||||
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
|
||||
|
@ -102,38 +102,38 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
static int omap2_gp_timer_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
__omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 period;
|
||||
|
||||
__omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
period = clkev.rate / HZ;
|
||||
period -= 1;
|
||||
/* Looks like we need to first set the load value separately */
|
||||
__omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
|
||||
0xffffffff - period, OMAP_TIMER_POSTED);
|
||||
__omap_dm_timer_load_start(&clkev,
|
||||
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
|
||||
0xffffffff - period, OMAP_TIMER_POSTED);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
period = clkev.rate / HZ;
|
||||
period -= 1;
|
||||
/* Looks like we need to first set the load value separately */
|
||||
__omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, 0xffffffff - period,
|
||||
OMAP_TIMER_POSTED);
|
||||
__omap_dm_timer_load_start(&clkev,
|
||||
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
|
||||
0xffffffff - period, OMAP_TIMER_POSTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_gpt = {
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = omap2_gp_timer_set_next_event,
|
||||
.set_mode = omap2_gp_timer_set_mode,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = omap2_gp_timer_set_next_event,
|
||||
.set_state_shutdown = omap2_gp_timer_shutdown,
|
||||
.set_state_periodic = omap2_gp_timer_set_periodic,
|
||||
.set_state_oneshot = omap2_gp_timer_shutdown,
|
||||
.tick_resume = omap2_gp_timer_shutdown,
|
||||
};
|
||||
|
||||
static struct property device_disabled = {
|
||||
|
@ -66,8 +66,6 @@
|
||||
static __iomem void *gpt_base;
|
||||
static struct clk *gpt_clk;
|
||||
|
||||
static void clockevent_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk_event_dev);
|
||||
static int clockevent_next_event(unsigned long evt,
|
||||
struct clock_event_device *clk_event_dev);
|
||||
|
||||
@ -95,54 +93,67 @@ static void __init spear_clocksource_init(void)
|
||||
200, 16, clocksource_mmio_readw_up);
|
||||
}
|
||||
|
||||
static struct clock_event_device clkevt = {
|
||||
.name = "tmr0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = clockevent_set_mode,
|
||||
.set_next_event = clockevent_next_event,
|
||||
.shift = 0, /* to be computed */
|
||||
};
|
||||
static inline void timer_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
u16 val = readw(gpt_base + CR(CLKEVT));
|
||||
|
||||
static void clockevent_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk_event_dev)
|
||||
/* stop the timer */
|
||||
val &= ~CTRL_ENABLE;
|
||||
writew(val, gpt_base + CR(CLKEVT));
|
||||
}
|
||||
|
||||
static int spear_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
timer_shutdown(evt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spear_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
/* stop the timer */
|
||||
timer_shutdown(evt);
|
||||
|
||||
val = readw(gpt_base + CR(CLKEVT));
|
||||
val |= CTRL_ONE_SHOT;
|
||||
writew(val, gpt_base + CR(CLKEVT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spear_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 period;
|
||||
u16 val;
|
||||
|
||||
/* stop the timer */
|
||||
timer_shutdown(evt);
|
||||
|
||||
period = clk_get_rate(gpt_clk) / HZ;
|
||||
period >>= CTRL_PRESCALER16;
|
||||
writew(period, gpt_base + LOAD(CLKEVT));
|
||||
|
||||
val = readw(gpt_base + CR(CLKEVT));
|
||||
val &= ~CTRL_ENABLE;
|
||||
val &= ~CTRL_ONE_SHOT;
|
||||
val |= CTRL_ENABLE | CTRL_INT_ENABLE;
|
||||
writew(val, gpt_base + CR(CLKEVT));
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
period = clk_get_rate(gpt_clk) / HZ;
|
||||
period >>= CTRL_PRESCALER16;
|
||||
writew(period, gpt_base + LOAD(CLKEVT));
|
||||
|
||||
val = readw(gpt_base + CR(CLKEVT));
|
||||
val &= ~CTRL_ONE_SHOT;
|
||||
val |= CTRL_ENABLE | CTRL_INT_ENABLE;
|
||||
writew(val, gpt_base + CR(CLKEVT));
|
||||
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
val = readw(gpt_base + CR(CLKEVT));
|
||||
val |= CTRL_ONE_SHOT;
|
||||
writew(val, gpt_base + CR(CLKEVT));
|
||||
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid mode requested\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device clkevt = {
|
||||
.name = "tmr0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = spear_shutdown,
|
||||
.set_state_periodic = spear_set_periodic,
|
||||
.set_state_oneshot = spear_set_oneshot,
|
||||
.tick_resume = spear_shutdown,
|
||||
.set_next_event = clockevent_next_event,
|
||||
.shift = 0, /* to be computed */
|
||||
};
|
||||
|
||||
static int clockevent_next_event(unsigned long cycles,
|
||||
struct clock_event_device *clk_event_dev)
|
||||
{
|
||||
|
@ -48,31 +48,32 @@
|
||||
|
||||
static unsigned int timer0_load;
|
||||
|
||||
static void nuc900_clockevent_setmode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
static int nuc900_clockevent_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = __raw_readl(REG_TCSR0);
|
||||
val &= ~(0x03 << 27);
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
__raw_writel(timer0_load, REG_TICR0);
|
||||
val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
|
||||
|
||||
__raw_writel(val, REG_TCSR0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nuc900_clockevent_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
|
||||
|
||||
val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
|
||||
|
||||
__raw_writel(val, REG_TCSR0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nuc900_clockevent_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
|
||||
|
||||
__raw_writel(timer0_load, REG_TICR0);
|
||||
val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
|
||||
__raw_writel(val, REG_TCSR0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nuc900_clockevent_setnextevent(unsigned long evt,
|
||||
@ -90,11 +91,15 @@ static int nuc900_clockevent_setnextevent(unsigned long evt,
|
||||
}
|
||||
|
||||
static struct clock_event_device nuc900_clockevent_device = {
|
||||
.name = "nuc900-timer0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = nuc900_clockevent_setmode,
|
||||
.set_next_event = nuc900_clockevent_setnextevent,
|
||||
.rating = 300,
|
||||
.name = "nuc900-timer0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = nuc900_clockevent_shutdown,
|
||||
.set_state_periodic = nuc900_clockevent_set_periodic,
|
||||
.set_state_oneshot = nuc900_clockevent_set_oneshot,
|
||||
.tick_resume = nuc900_clockevent_shutdown,
|
||||
.set_next_event = nuc900_clockevent_setnextevent,
|
||||
.rating = 300,
|
||||
};
|
||||
|
||||
/*IRQ handler for the timer*/
|
||||
|
@ -77,41 +77,57 @@ static int iop_set_next_event(unsigned long delta,
|
||||
|
||||
static unsigned long ticks_per_jiffy;
|
||||
|
||||
static void iop_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *unused)
|
||||
static int iop_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmr = read_tmr0();
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
write_tmr0(tmr & ~IOP_TMR_EN);
|
||||
write_tcr0(ticks_per_jiffy - 1);
|
||||
write_trr0(ticks_per_jiffy - 1);
|
||||
tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* ->set_next_event sets period and enables timer */
|
||||
tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
tmr |= IOP_TMR_EN;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
default:
|
||||
tmr &= ~IOP_TMR_EN;
|
||||
break;
|
||||
}
|
||||
write_tmr0(tmr & ~IOP_TMR_EN);
|
||||
write_tcr0(ticks_per_jiffy - 1);
|
||||
write_trr0(ticks_per_jiffy - 1);
|
||||
tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
|
||||
write_tmr0(tmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iop_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmr = read_tmr0();
|
||||
|
||||
/* ->set_next_event sets period and enables timer */
|
||||
tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
write_tmr0(tmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iop_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmr = read_tmr0();
|
||||
|
||||
tmr &= ~IOP_TMR_EN;
|
||||
write_tmr0(tmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iop_resume(struct clock_event_device *evt)
|
||||
{
|
||||
u32 tmr = read_tmr0();
|
||||
|
||||
tmr |= IOP_TMR_EN;
|
||||
write_tmr0(tmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device iop_clockevent = {
|
||||
.name = "iop_timer0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = iop_set_next_event,
|
||||
.set_mode = iop_set_mode,
|
||||
.name = "iop_timer0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = iop_set_next_event,
|
||||
.set_state_shutdown = iop_shutdown,
|
||||
.set_state_periodic = iop_set_periodic,
|
||||
.tick_resume = iop_resume,
|
||||
.set_state_oneshot = iop_set_oneshot,
|
||||
};
|
||||
|
||||
static irqreturn_t
|
||||
|
@ -106,60 +106,63 @@ orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
|
||||
static int orion_clkevt_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 u;
|
||||
|
||||
local_irq_save(flags);
|
||||
if (mode == CLOCK_EVT_MODE_PERIODIC) {
|
||||
/*
|
||||
* Setup timer to fire at 1/HZ intervals.
|
||||
*/
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
|
||||
|
||||
/*
|
||||
* Enable timer interrupt.
|
||||
*/
|
||||
u = readl(bridge_base + BRIDGE_MASK_OFF);
|
||||
writel(u | BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
|
||||
/* Disable timer */
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
/*
|
||||
* Enable timer.
|
||||
*/
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u | TIMER1_EN | TIMER1_RELOAD_EN,
|
||||
timer_base + TIMER_CTRL_OFF);
|
||||
} else {
|
||||
/*
|
||||
* Disable timer.
|
||||
*/
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
|
||||
/* Disable timer interrupt */
|
||||
u = readl(bridge_base + BRIDGE_MASK_OFF);
|
||||
writel(u & ~BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
|
||||
|
||||
/*
|
||||
* Disable timer interrupt.
|
||||
*/
|
||||
u = readl(bridge_base + BRIDGE_MASK_OFF);
|
||||
writel(u & ~BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
|
||||
/* ACK pending timer interrupt */
|
||||
writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
|
||||
|
||||
/*
|
||||
* ACK pending timer interrupt.
|
||||
*/
|
||||
writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
|
||||
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int orion_clkevt_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 u;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Setup timer to fire at 1/HZ intervals */
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
|
||||
writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
|
||||
|
||||
/* Enable timer interrupt */
|
||||
u = readl(bridge_base + BRIDGE_MASK_OFF);
|
||||
writel(u | BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
|
||||
|
||||
/* Enable timer */
|
||||
u = readl(timer_base + TIMER_CTRL_OFF);
|
||||
writel(u | TIMER1_EN | TIMER1_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device orion_clkevt = {
|
||||
.name = "orion_tick",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
|
||||
.rating = 300,
|
||||
.set_next_event = orion_clkevt_next_event,
|
||||
.set_mode = orion_clkevt_mode,
|
||||
.name = "orion_tick",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_PERIODIC,
|
||||
.rating = 300,
|
||||
.set_next_event = orion_clkevt_next_event,
|
||||
.set_state_shutdown = orion_clkevt_shutdown,
|
||||
.set_state_periodic = orion_clkevt_set_periodic,
|
||||
.set_state_oneshot = orion_clkevt_shutdown,
|
||||
.tick_resume = orion_clkevt_shutdown,
|
||||
};
|
||||
|
||||
static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user