diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 14:03:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 14:03:14 -0700 |
commit | 0fe41b8982001cd14ee2c77cd776735a5024e98b (patch) | |
tree | 83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/mach-gemini/time.c | |
parent | eedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff) | |
parent | 9759d22c8348343b0da4e25d6150c41712686c14 (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits)
[ARM] 5435/1: fix compile warning in sanity_check_meminfo()
[ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx
[ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0
[ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins
imxfb: Fix TFT mode
i.MX21/27: remove ifdef CONFIG_FB_IMX
imxfb: add clock support
mxc: add arch_reset() function
clkdev: add possibility to get a clock based on the device name
i.MX1: remove fb support from mach-imx
[ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined
Gemini: Add support for Teltonika RUT100
Gemini: gpiolib based GPIO support v2
MAINTAINERS: add myself as Gemini architecture maintainer
ARM: Add Gemini architecture v3
[ARM] OMAP: Fix compile for omap2_init_common_hw()
MAINTAINERS: Add myself as Faraday ARM core variant maintainer
ARM: Add support for FA526 v2
[ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h
[ARM] collie: fix two minor formatting nits
...
Diffstat (limited to 'arch/arm/mach-gemini/time.c')
-rw-r--r-- | arch/arm/mach-gemini/time.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c new file mode 100644 index 00000000000..21dc5a89d1c --- /dev/null +++ b/arch/arm/mach-gemini/time.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2001-2006 Storlink, Corp. + * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/global_reg.h> +#include <asm/mach/time.h> + +/* + * Register definitions for the timers + */ +#define TIMER_COUNT(BASE_ADDR) (BASE_ADDR + 0x00) +#define TIMER_LOAD(BASE_ADDR) (BASE_ADDR + 0x04) +#define TIMER_MATCH1(BASE_ADDR) (BASE_ADDR + 0x08) +#define TIMER_MATCH2(BASE_ADDR) (BASE_ADDR + 0x0C) +#define TIMER_CR(BASE_ADDR) (BASE_ADDR + 0x30) + +#define TIMER_1_CR_ENABLE (1 << 0) +#define TIMER_1_CR_CLOCK (1 << 1) +#define TIMER_1_CR_INT (1 << 2) +#define TIMER_2_CR_ENABLE (1 << 3) +#define TIMER_2_CR_CLOCK (1 << 4) +#define TIMER_2_CR_INT (1 << 5) +#define TIMER_3_CR_ENABLE (1 << 6) +#define TIMER_3_CR_CLOCK (1 << 7) +#define TIMER_3_CR_INT (1 << 8) + +/* + * IRQ handler for the timer + */ +static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) +{ + timer_tick(); + + return IRQ_HANDLED; +} + +static struct irqaction gemini_timer_irq = { + .name = "Gemini Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = gemini_timer_interrupt, +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init gemini_timer_init(void) +{ + unsigned int tick_rate, reg_v; + + reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); + tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000; + + printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); + + tick_rate /= 6; /* APB bus run AHB*(1/6) */ + + switch(reg_v & CPU_AHB_RATIO_MASK) { + case CPU_AHB_1_1: + printk(KERN_CONT "(1/1)\n"); + break; + case CPU_AHB_3_2: + printk(KERN_CONT "(3/2)\n"); + break; + case CPU_AHB_24_13: + printk(KERN_CONT "(24/13)\n"); + break; + case CPU_AHB_2_1: + printk(KERN_CONT "(2/1)\n"); + break; + } + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMER2, &gemini_timer_irq); + /* Start the timer */ + __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); + __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); + __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +} |