struct sys_timer s3c24xx_timer =
{
.init =
s3c2410_timer_init,
.offset =
s3c2410_gettimeoffset,
.resume =
s3c2410_timer_setup
};
Mini2440系统时钟节拍定义在arch\arm\plat-s3c\Time.c.
static void __init s3c2410_timer_init(void)
{
s3c2410_timer_resources();
s3c2410_timer_setup();
setup_irq(IRQ_TIMER4,
&s3c2410_timer_irq);//使用定时器4产生中断,s3c2410_timer_irq为irqaction类型结构体}
static void __init s3c2410_timer_resources(void)
{
struct platform_device tmpdev;
tmpdev.dev.bus =
&platform_bus_type;
tmpdev.id = 4;
timerclk = clk_get(NULL, "timers");
if (IS_ERR(timerclk))
panic("failed to get clock for
system timer");
clk_enable(timerclk);
if (!use_tclk1_12()) {
tin =
clk_get(&tmpdev.dev, "pwm-tin");
if (IS_ERR(tin))
panic("failed
to get pwm-tin clock for system timer");
tdiv =
clk_get(&tmpdev.dev, "pwm-tdiv");
if (IS_ERR(tdiv))
panic("failed
to get pwm-tdiv clock for system timer");
}
clk_enable(tin);
}
static void s3c2410_timer_setup (void)
{
unsigned long tcon;
unsigned long tcnt;
unsigned long tcfg1;
unsigned long tcfg0;
tcnt = TICK_MAX;
if (use_tclk1_12()) {
timer_usec_ticks =
timer_mask_usec_ticks(1, 12000000);
tcnt = 12000000 / HZ;
tcfg1 =
__raw_readl(S3C2410_TCFG1);
tcfg1 &=
~S3C2410_TCFG1_MUX4_MASK;
tcfg1 |=
S3C2410_TCFG1_MUX4_TCLK1;
__raw_writel(tcfg1,
S3C2410_TCFG1);
} else {
unsigned long pclk;
struct clk *tscaler;
pclk =
clk_get_rate(timerclk);
timer_usec_ticks =
timer_mask_usec_ticks(6, pclk);
tscaler =
clk_get_parent(tdiv);
clk_set_rate(tscaler, pclk /
3);
clk_set_rate(tdiv, pclk /
6);
clk_set_parent(tin, tdiv);
tcnt = clk_get_rate(tin) /
HZ;
}
tcon = __raw_readl(S3C2410_TCON);
tcfg0 = __raw_readl(S3C2410_TCFG0);
tcfg1 = __raw_readl(S3C2410_TCFG1);
tcnt--;
printk(KERN_DEBUG "timer tcon=lx, tcnt lx,
tcfg lx,lx, usec lx\n",
tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
if (tcnt > TICK_MAX) {
panic("setup_timer: HZ is too
small, cannot configure timer!");
return;
}
__raw_writel(tcfg1, S3C2410_TCFG1);
__raw_writel(tcfg0, S3C2410_TCFG0);
timer_startval = tcnt;
__raw_writel(tcnt, S3C2410_TCNTB(4));
tcon &=
~(7<<20);
tcon |= S3C2410_TCON_T4RELOAD;
tcon |= S3C2410_TCON_T4MANUALUPD;
__raw_writel(tcon, S3C2410_TCON);
__raw_writel(tcnt, S3C2410_TCNTB(4));
__raw_writel(tcnt, S3C2410_TCMPB(4));
tcon |= S3C2410_TCON_T4START;
tcon &=
~S3C2410_TCON_T4MANUALUPD;
__raw_writel(tcon, S3C2410_TCON);
}
static struct irqaction s3c2410_timer_irq =
{
.name =
"S3C2410 Timer Tick",
.flags =
IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler =
s3c2410_timer_interrupt,
};
.handler是系统节拍中断函数
static irqreturn_t
s3c2410_timer_interrupt(int irq, void *dev_id)
{
timer_tick();
return IRQ_HANDLED;
}
timer_tick()是系统提供的一个函数,完成与节拍有关的系统任务。