Commit 13ffe5f8 authored by Deepak Saxena's avatar Deepak Saxena

[ARM] Timer cleanup

Signed-off-by: default avatarDeepak Saxena <dsaxena@plexity.net>
parent 981a1ad3
......@@ -191,6 +191,11 @@ config ARCH_ACORN
depends on ARCH_RPC
default y
config TIMER_ACORN
bool
depends on ARCH_ACORN || ARCH_CLPS7500
default y
#####################################################################
# Footbridge support
config FOOTBRIDGE
......
......@@ -9,3 +9,4 @@ obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_TIMER_ACORN) += time-acorn.o
/*
* linux/arch/arm/kernel/time-acorn.c
* linux/arch/arm/common/time-acorn.c
*
* Copyright (c) 1996-2000 Russell King.
*
......@@ -11,6 +11,7 @@
* 24-Sep-1996 RMK Created
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
* 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500
*/
#include <linux/timex.h>
#include <linux/init.h>
......@@ -19,7 +20,7 @@
#include <asm/io.h>
#include <asm/hardware/ioc.h>
extern unsigned long (*gettimeoffset)(void);
#include <asm/mach/time.h>
static unsigned long ioctime_gettimeoffset(void)
{
......
......@@ -11,8 +11,7 @@ obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \
time.o traps.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o
obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
obj-$(CONFIG_FOOTBRIDGE) += isa.o
obj-$(CONFIG_FIQ) += fiq.o
obj-$(CONFIG_MODULES) += armksyms.o module.o
......
......@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
#include <asm/elf.h>
#include <asm/hardware.h>
......@@ -34,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
......@@ -727,6 +729,7 @@ void __init setup_arch(char **cmdline_p)
* Set up various architecture-specific pointers
*/
init_arch_irq = mdesc->init_irq;
init_arch_time = mdesc->init_time;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
......
......@@ -27,12 +27,15 @@
#include <linux/errno.h>
#include <linux/profile.h>
#include <linux/sysdev.h>
#include <linux/timer.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach/time.h>
u64 jiffies_64 = INITIAL_JIFFIES;
EXPORT_SYMBOL(jiffies_64);
......@@ -83,7 +86,7 @@ unsigned long long __attribute__((weak)) sched_clock(void)
/*
* Handle kernel profile stuff...
*/
static inline void do_profile(struct pt_regs *regs)
void do_profile(struct pt_regs *regs)
{
profile_hook(regs);
......@@ -113,7 +116,7 @@ static unsigned long next_rtc_update;
* called as close as possible to 500 ms before the new second
* starts.
*/
static inline void do_set_rtc(void)
void do_set_rtc(void)
{
if (time_status & STA_UNSYNC || set_rtc == NULL)
return;
......@@ -237,8 +240,7 @@ device_initcall(leds_init);
EXPORT_SYMBOL(leds_event);
#endif
#ifdef CONFIG_LEDS_TIMER
static void do_leds(void)
void do_leds(void)
{
static unsigned int count = 50;
......@@ -247,9 +249,6 @@ static void do_leds(void)
leds_event(led_timer);
}
}
#else
#define do_leds()
#endif
void do_gettimeofday(struct timeval *tv)
{
......@@ -316,12 +315,10 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
static struct irqaction timer_irq = {
.name = "timer",
.flags = SA_INTERRUPT,
};
void (*init_arch_time)(void);
void __init time_init(void)
{
init_arch_time();
}
/*
* Include architecture specific code
*/
#include <asm/arch/time.h>
......@@ -37,6 +37,7 @@
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
/*
* The on-chip registers are given a size of 1MB so that a section can
......@@ -65,5 +66,6 @@ MACHINE_START(AUTCPU12, "autronix autcpu12")
BOOT_PARAMS(0xc0020000)
MAPIO(autcpu12_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clp711x_init_time)
MACHINE_END
......@@ -34,6 +34,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x-init_time(void);
/*
* Map the CS89712 Ethernet port. That should be moved to the
......@@ -55,6 +56,7 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712")
BOOT_PARAMS(0xc0000100)
MAPIO(cdb89712_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
static int cdb89712_hw_init(void)
......
......@@ -35,6 +35,7 @@
#include <asm/mach/map.h>
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
static struct map_desc ceiva_io_desc[] __initdata = {
/* virtual, physical, length, type */
......@@ -58,4 +59,5 @@ MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
BOOT_PARAMS(0xc0000100)
MAPIO(ceiva_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
......@@ -25,6 +25,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x_init_time(void);
static void __init
fixup_clep7312(struct machine_desc *desc, struct tag *tags,
......@@ -44,5 +45,6 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
FIXUP(fixup_clep7312)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
......@@ -27,6 +27,7 @@
extern void clps711x_init_irq(void);
extern void edb7211_map_io(void);
extern void clps711x_init_time(void);
static void __init
fixup_edb7211(struct machine_desc *desc, struct tag *tags,
......@@ -56,4 +57,5 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
FIXUP(fixup_edb7211)
MAPIO(edb7211_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
......@@ -33,6 +33,7 @@
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
struct meminfo memmap = {
.nr_banks = 1,
......@@ -82,4 +83,5 @@ MACHINE_START(FORTUNET, "ARM-FortuNet")
FIXUP(fortunet_fixup)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
......@@ -36,6 +36,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x_init_time(void);
/*
* Map the P720T system PLD. It occupies two address spaces:
......@@ -86,6 +87,7 @@ MACHINE_START(P720T, "ARM-Prospector720T")
FIXUP(fixup_p720t)
MAPIO(p720t_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
MACHINE_END
static int p720t_hw_init(void)
......
......@@ -18,12 +18,17 @@
*/
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/io.h>
#include <asm/hardware/clps7111.h>
extern unsigned long (*gettimeoffset)(void);
#include <asm/mach/time.h>
/*
* gettimeoffset() returns time since last timer tick, in usecs.
......@@ -38,19 +43,38 @@ static unsigned long clps711x_gettimeoffset(void)
return (hwticks * (tick_nsec / 1000)) / LATCH;
}
void __init clps711x_setup_timer(void)
/*
* IRQ handler for the timer
*/
static irqreturn_t
p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction clps711x_timer_irq = {
.name = "CLPS711x Timer Tick",
.flags = SA_INTERRUPT,
.handler = p720t_timer_interrupt
};
void __init clps711x_init_time(void)
{
struct timespec tv;
unsigned int syscon;
gettimeoffset = clps711x_gettimeoffset;
syscon = clps_readl(SYSCON1);
syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
clps_writel(syscon, SYSCON1);
clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
gettimeoffset = clps711x_gettimeoffset;
tv.tv_nsec = 0;
tv.tv_sec = clps_readl(RTCDR);
do_settimeofday(&tv);
......
......@@ -10,12 +10,13 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/hardware.h>
#include <asm/hardware/iomd.h>
......@@ -265,10 +266,48 @@ static void __init clps7500_map_io(void)
iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc));
}
extern void ioctime_init(void);
static irqreturn_t
clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
do_set_rtc();
do_profile(regs);
{
/* Twinkle the lights. */
static int count, state = 0xff00;
if (count-- == 0) {
state ^= 0x100;
count = 25;
*((volatile unsigned int *)LED_ADDRESS) = state;
}
}
return IRQ_HANDLED;
}
static struct irqaction clps7500_timer_irq = {
.name = "CLPS7500 Timer Tick",
.flags = SA_INTERRUPT,
.handler = clps7500_timer_interrupt
};
/*
* Set up timer interrupt.
*/
void __init clps7500_init_time(void)
{
ioctime_init();
setup_irq(IRQ_TIMER, &clps7500_timer_irq);
}
MACHINE_START(CLPS7500, "CL-PS7500")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
MAPIO(clps7500_map_io)
INITIRQ(clps7500_init_irq)
INITTIME(clps7500_init_time)
MACHINE_END
......@@ -26,6 +26,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#define IRQ_MASK 0xfe000000 /* read */
#define IRQ_MSET 0xfe000000 /* write */
#define IRQ_STAT 0xff000000 /* read */
......@@ -89,6 +91,105 @@ static void __init ebsa110_map_io(void)
iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
}
#define PIT_CTRL (PIT_BASE + 0x0d)
#define PIT_T2 (PIT_BASE + 0x09)
#define PIT_T1 (PIT_BASE + 0x05)
#define PIT_T0 (PIT_BASE + 0x01)
/*
* This is the rate at which your MCLK signal toggles (in Hz)
* This was measured on a 10 digit frequency counter sampling
* over 1 second.
*/
#define MCLK 47894000
/*
* This is the rate at which the PIT timers get clocked
*/
#define CLKBY7 (MCLK / 7)
/*
* This is the counter value. We tick at 200Hz on this platform.
*/
#define COUNT ((CLKBY7 + (HZ / 2)) / HZ)
/*
* Get the time offset from the system PIT. Note that if we have missed an
* interrupt, then the PIT counter will roll over (ie, be negative).
* This actually works out to be convenient.
*/
static unsigned long ebsa110_gettimeoffset(void)
{
unsigned long offset, count;
__raw_writeb(0x40, PIT_CTRL);
count = __raw_readb(PIT_T1);
count |= __raw_readb(PIT_T1) << 8;
/*
* If count > COUNT, make the number negative.
*/
if (count > COUNT)
count |= 0xffff0000;
offset = COUNT;
offset -= count;
/*
* `offset' is in units of timer counts. Convert
* offset to units of microseconds.
*/
offset = offset * (1000000 / HZ) / COUNT;
return offset;
}
static irqreturn_t
ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 count;
/* latch and read timer 1 */
__raw_writeb(0x40, PIT_CTRL);
count = __raw_readb(PIT_T1);
count |= __raw_readb(PIT_T1) << 8;
count += COUNT;
__raw_writeb(count & 0xff, PIT_T1);
__raw_writeb(count >> 8, PIT_T1);
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction ebsa110_timer_irq = {
.name = "EBSA110 Timer Tick",
.flags = SA_INTERRUPT,
.handler = ebsa110_timer_interrupt
};
/*
* Set up timer interrupt.
*/
void __init ebsa110_time_init(void)
{
/*
* Timer 1, mode 2, LSB/MSB
*/
__raw_writeb(0x70, PIT_CTRL);
__raw_writeb(COUNT & 0xff, PIT_T1);
__raw_writeb(COUNT >> 8, PIT_T1);
gettimeoffset = ebsa110_gettimeoffset;
setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
}
MACHINE_START(EBSA110, "EBSA110")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
......@@ -98,4 +199,5 @@ MACHINE_START(EBSA110, "EBSA110")
SOFT_REBOOT
MAPIO(ebsa110_map_io)
INITIRQ(ebsa110_init_irq)
INITTIME(ebsa110_init_time)
MACHINE_END
......@@ -29,10 +29,13 @@
extern void epxa10db_map_io(void);
extern void epxa10db_init_irq(void);
extern void epxa10db_init_time(void);
MACHINE_START(CAMELOT, "Altera Epxa10db")
MAINTAINER("Altera Corporation")
BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
MAPIO(epxa10db_map_io)
INITIRQ(epxa10db_init_irq)
INITTIME(epxa10db_init_time)
MACHINE_END
......@@ -10,11 +10,17 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach/time.h>
extern int (*set_rtc)(void);
#define TIMER00_TYPE (volatile unsigned int*)
#include <asm/arch/timer00.h>
static int epxa10db_set_rtc(void)
{
......@@ -29,3 +35,41 @@ static int epxa10db_rtc_init(void)
}
__initcall(epxa10db_rtc_init);
/*
* IRQ handler for the timer
*/
static irqreturn_t
epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
// ...clear the interrupt
*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction epxa10db_timer_irq = {
.name = "Excalibur Timer Tick",
.flags = SA_INTERRUPT,
.handler = epxa10db_timer_interrupt
};
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init epxa10db_init_time(void)
{
/* Start the timer */
*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
setup_irq(IRQ_TIMER0, &epxa10db_timer_irq);
}
......@@ -4,7 +4,7 @@
# Object file lists.
obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o
obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o time.o
obj-m :=
obj-n :=
obj- :=
......
......@@ -22,6 +22,7 @@
extern void footbridge_map_io(void);
extern void footbridge_init_irq(void);
extern void footbridge_init_time(void);
unsigned int mem_fclk_21285 = 50000000;
......@@ -43,6 +44,7 @@ MACHINE_START(EBSA285, "EBSA285")
VIDEO(0x000a0000, 0x000bffff)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -78,6 +80,7 @@ MACHINE_START(NETWINDER, "Rebel-NetWinder")
FIXUP(fixup_netwinder)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -103,6 +106,7 @@ MACHINE_START(CATS, "Chalice-CATS")
FIXUP(fixup_cats)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -129,6 +133,7 @@ MACHINE_START(CO285, "co-EBSA285")
FIXUP(fixup_coebsa285)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -139,5 +144,6 @@ MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
BOOT_PARAMS(0x00000100)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -17,12 +17,23 @@
#define RTC_PORT(x) (rtc_base+(x))
#define RTC_ALWAYS_BCD 0
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/mc146818rtc.h>
#include <linux/bcd.h>
#include <asm/hardware/dec21285.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/hardware/clps7111.h>
#include <asm/mach/time.h>
static int rtc_base;
......@@ -204,13 +215,15 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
static struct irqaction footbridge_timer_irq = {
.flags = SA_INTERRUPT
};
/*
* Set up timer interrupt.
*/
void __init time_init(void)
void __init footbridge_init_time(void)
{
int irq;
if (machine_is_co285() ||
machine_is_personal_server())
/*
......@@ -270,8 +283,11 @@ void __init time_init(void)
*CSR_TIMER1_LOAD = timer1_latch;
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
timer_irq.handler = timer1_interrupt;
irq = IRQ_TIMER1;
footbridge_timer_irq.name = "Timer1 Timer Tick";
footbrdige_timer_irq.handler = timer1_interrupt;
setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
} else {
/* enable PIT timer */
/* set for periodic (4) and LSB/MSB write (0x30) */
......@@ -280,8 +296,10 @@ void __init time_init(void)
outb((mSEC_10_from_14/6) >> 8, 0x40);
gettimeoffset = isa_gettimeoffset;
timer_irq.handler = isa_timer_interrupt;
irq = IRQ_ISA_TIMER;
footbridge_timer_irq.name = "ISA Timer Tick";
footbrdige_timer_irq.handler = isa_timer_interrupt;
setup_irq(IRQ_ISA, &footbridge_timer_irq);
}
setup_irq(irq, &timer_irq);
}
......@@ -88,6 +88,53 @@ static void __init ftvpci_map_io(void)
iotable_init(ftvpci_io_desc, ARRAY_SIZE(ftvpci_io_desc));
}
static irqreturn_t
ftvpci_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
static int count = 25;
unsigned char stat = __raw_readb(DUART_BASE + 0x14);
if (!(stat & 0x10))
return; /* Not for us */
/* Reset counter */
__raw_writeb(0x90, DUART_BASE + 8);
if (--count == 0) {
static int state = 1;
state ^= 1;
__raw_writeb(0x1a + state, INTCONT_BASE);
__raw_writeb(0x18 + state, INTCONT_BASE);
count = 50;
}
/* Wait for slow rise time */
__raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14);
do_timer(regs);
return IRQ_HANDLED;
}
void __init ftvpci_time_init(void)
{
int tick = 3686400 / 16 / 2 / 100;
__raw_writeb(tick & 0xff, DUART_BASE + 0x1c);
__raw_writeb(tick >> 8, DUART_BASE + 0x18);
__raw_writeb(0x80, DUART_BASE + 8);
__raw_writeb(0x10, DUART_BASE + 0x14);
timer_irq.handler = timer_interrupt;
timer_irq.flags = SA_SHIRQ;
set_timer_irq_handler(IRQ_TIMER, timer_interrupt);
}
MACHINE_START(NEXUSPCI, "FTV/PCI")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x40000000, 0x10000000, 0xe0000000)
......
......@@ -281,11 +281,17 @@ static void __init ap_init(void)
}
}
static void ap_time_init(void)
{
integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
}
MACHINE_START(INTEGRATOR, "ARM-Integrator")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(ap_map_io)
INITIRQ(ap_init_irq)
INITTIME(ap_time_init)
INIT_MACHINE(ap_init)
MACHINE_END
......@@ -357,11 +357,17 @@ static void __init intcp_init(void)
}
}
static void __init intcp_init_time(void)
{
integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
}
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(intcp_map_io)
INITIRQ(intcp_init_irq)
INITTIME(intcp_init_time)
INIT_MACHINE(intcp_init)
MACHINE_END
......@@ -10,9 +10,16 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/time.h>
#define RTC_DR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)
#define RTC_MR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)
......@@ -44,3 +51,142 @@ static int integrator_rtc_init(void)
}
__initcall(integrator_rtc_init);
/*
* Where is the timer (VA)?
*/
#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
/*
* How long is the timer interval?
*/
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
#if TIMER_INTERVAL >= 0x100000
#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
#elif TIMER_INTERVAL >= 0x10000
#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
#else
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
/*
* What does it look like?
*/
typedef struct TimerStruct {
unsigned long TimerLoad;
unsigned long TimerValue;
unsigned long TimerControl;
unsigned long TimerClear;
} TimerStruct_t;
extern unsigned long (*gettimeoffset)(void);
static unsigned long timer_reload;
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long integrator_gettimeoffset(void)
{
volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
unsigned long ticks1, ticks2, status;
/*
* Get the current number of ticks. Note that there is a race
* condition between us reading the timer and checking for
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
ticks2 = timer1->TimerValue & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
ticks2 = timer1->TimerValue & 0xffff;
} while (ticks2 > ticks1);
/*
* Number of ticks since last interrupt.
*/
ticks1 = timer_reload - ticks2;
/*
* Interrupt pending? If so, we've reloaded once already.
*/
if (status & (1 << IRQ_TIMERINT1))
ticks1 += timer_reload;
/*
* Convert the ticks to usecs
*/
return TICKS2USECS(ticks1);
}
/*
* IRQ handler for the timer
*/
static irqreturn_t
integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
// ...clear the interrupt
timer1->TimerClear = 1;
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction integrator_timer_irq = {
.name = "Integrator Timer Tick",
.flags = SA_INTERRUPT,
.handler = integrator_timer_interrupt
};
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
{
volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
timer_reload = reload;
timer_ctrl |= ctrl;
if (timer_reload > 0x100000) {
timer_reload >>= 8;
timer_ctrl |= 0x08; /* /256 */
} else if (timer_reload > 0x010000) {
timer_reload >>= 4;
timer_ctrl |= 0x04; /* /16 */
}
/*
* Initialise to a known state (all timers off)
*/
timer0->TimerControl = 0;
timer1->TimerControl = 0;
timer2->TimerControl = 0;
timer1->TimerLoad = timer_reload;
timer1->TimerValue = timer_reload;
timer1->TimerControl = timer_ctrl;
/*
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
gettimeoffset = integrator_gettimeoffset;
}
......@@ -29,6 +29,7 @@ extern void iq80310_init_irq(void);
#ifdef CONFIG_ARCH_IQ80321
extern void iq80321_map_io(void);
extern void iop321_init_irq(void);
extern void iop321_init_time(void);
#endif
#ifdef CONFIG_ARCH_IQ80310
......@@ -67,6 +68,7 @@ MACHINE_START(IQ80321, "Intel IQ80321")
FIXUP(fixup_iop321)
MAPIO(iq80321_map_io)
INITIRQ(iop321_init_irq)
INITTIME(iop321_init_time)
MACHINE_END
#else
......
......@@ -23,7 +23,9 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
static unsigned long iop321_gettimeoffset(void)
{
......@@ -66,22 +68,21 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
extern unsigned long (*gettimeoffset)(void);
static struct irqaction timer_irq = {
.name = "timer",
static struct irqaction iop321_timer_irq = {
.name = "IOP321 Timer Tick",
.handler = iop321_timer_interrupt,
.flags = SA_INTERRUPT
};
extern int setup_arm_irq(int, struct irqaction*);
void __init time_init(void)
void __init iop321_init_time(void)
{
u32 timer_ctl;
u32 latch = LATCH;
gettimeoffset = iop321_gettimeoffset;
setup_irq(IRQ_IOP321_TIMER0, &timer_irq);
setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
IOP321_TMR_RATIO_1_1;
......
......@@ -36,6 +36,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
/*************************************************************************
......@@ -234,17 +235,15 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs
return IRQ_HANDLED;
}
extern unsigned long (*gettimeoffset)(void);
static struct irqaction timer_irq = {
static struct irqaction ixp4xx_timer_irq = {
.name = "IXP4xx Timer Tick",
.flags = SA_INTERRUPT
.flags = SA_INTERRUPT,
.handler = ixp4xx_timer_interrupt
};
void __init time_init(void)
void __init ixp4xx_init_time(void)
{
gettimeoffset = ixp4xx_gettimeoffset;
timer_irq.handler = ixp4xx_timer_interrupt;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
......@@ -257,7 +256,7 @@ void __init time_init(void)
last_jiffy_time = 0;
/* Connect the interrupt handler and enable the interrupt */
setup_irq(IRQ_IXP4XX_TIMER1, &timer_irq);
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
}
......@@ -84,6 +84,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering IXP4XX Coyote Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(coyote_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(coyote_init)
MACHINE_END
......
......@@ -113,6 +113,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......@@ -123,6 +124,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......@@ -140,6 +142,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......
......@@ -84,6 +84,7 @@ MACHINE_START(PRPMC1100, "Motorola PrPMC1100")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(prpmc1100_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(prpmc1100_init)
MACHINE_END
......
......@@ -4,7 +4,7 @@
# Object file lists.
obj-y := fiq.o
obj-y := fiq.o time.o
# generic.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a400.o
......
......@@ -25,6 +25,7 @@
/* This function calls the board specific IRQ initialization function. */
extern void lh7a400_init_irq (void);
extern void lh7a40x_init_time (void);
static struct map_desc kev7a400_io_desc[] __initdata = {
{ IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
......@@ -108,4 +109,5 @@ MACHINE_START (KEV7A400, "Sharp KEV7a400")
BOOT_PARAMS (0xc0000100)
MAPIO (kev7a400_map_io)
INITIRQ (lh7a400_init_irq)
INITTIME (lh7a40x_init_time)
MACHINE_END
......@@ -280,6 +280,7 @@ MACHINE_END
#ifdef CONFIG_MACH_LPD7A404
extern void lh7a404_init_irq (void);
extern void lh7a40x_init_time (void);
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
MAINTAINER ("Marc Singer")
......@@ -287,6 +288,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
BOOT_PARAMS (0xc0000100)
MAPIO (lpd7a400_map_io)
INITIRQ (lh7a404_init_irq)
INITTIME (lh7a40x_init_time)
INIT_MACHINE (lpd7a40x_init)
MACHINE_END
......
/* include/asm-arm/arch-lh7a40x/time.h
/*
* arch/arm/mach-lh7a40x/time.c
*
* Copyright (C) 2004 Logic Product Development
*
......@@ -7,6 +8,18 @@
* version 2 as published by the Free Software Foundation.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach/time.h>
#if HZ < 100
# define TIMER_CONTROL TIMER_CONTROL1
......@@ -36,16 +49,20 @@ lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
void __init time_init(void)
static struct irqaction lh7a40x_timer_irq = {
.name = "LHA740x Timer Tick",
.flags = SA_INTERRUPT,
.handler = lh7a40x_timer_interrupt
};
void __init lh7a40x_init_time(void)
{
/* Stop/disable all timers */
TIMER_CONTROL1 = 0;
TIMER_CONTROL2 = 0;
TIMER_CONTROL3 = 0;
timer_irq.handler = lh7a40x_timer_interrupt;
timer_irq.flags |= SA_INTERRUPT;
setup_irq (TIMER_IRQ, &timer_irq);
setup_irq (TIMER_IRQ, &lh7a40x_timer_irq);
TIMER_LOAD = TIMER_CONSTANT;
TIMER_CONTROL = TIMER_MODE;
......
......@@ -3,7 +3,7 @@
#
# Common support
obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o
obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o time.o
obj-m :=
obj-n :=
obj- :=
......
......@@ -64,6 +64,11 @@ static void __init omap_generic_map_io(void)
omap_map_io();
}
static void __init omap_generic_init_time(void)
{
omap_init_time();
}
MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
......@@ -71,4 +76,6 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610")
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
INITTIME(omap_generic_init_time)
MACHINE_END
......@@ -153,5 +153,6 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
BOOT_PARAMS(0x10000100)
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(innovator_init)
MACHINE_END
......@@ -93,5 +93,6 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
BOOT_PARAMS(0x10000100)
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(osk_init)
MACHINE_END
......@@ -107,5 +107,6 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(omap_perseus2_init)
MACHINE_END
......@@ -28,6 +28,7 @@
#define __ARCH_ARM_MACH_OMAP_COMMON_H
extern void omap_map_io(void);
extern void omap_init_time(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
......
/*
* linux/include/asm-arm/arch-omap/time.h
* arch/arm/mach-omap/time.c
*
* 32kHz timer definition
* OMAP Timer Tick
*
* Copyright (C) 2000 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
......@@ -26,8 +26,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(__ASM_ARCH_OMAP_TIME_H)
#define __ASM_ARCH_OMAP_TIME_H
#include <linux/config.h>
#include <linux/delay.h>
......@@ -37,6 +35,7 @@
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/arch/clocks.h>
#ifndef __instrument
......@@ -162,14 +161,14 @@ unsigned long __noinstrument machinecycles_to_usecs(unsigned long mputicks)
*/
static unsigned long systimer_mark;
static unsigned long omap1510_gettimeoffset(void)
static unsigned long omap_gettimeoffset(void)
{
/* Return elapsed usecs since last system timer ISR */
return machinecycles_to_usecs(do_getmachinecycles() - systimer_mark);
}
static irqreturn_t
omap1510_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
omap_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long now, ilatency;
......@@ -191,22 +190,25 @@ omap1510_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
void __init time_init(void)
static struct irqaction omap_timer_irq = {
.name = "OMAP Timer Tick",
.flags = SA_INTERRUPT,
.handler = omap_timer_interrupt
};
void __init omap_init_time(void)
{
/* Since we don't call request_irq, we must init the structure */
gettimeoffset = omap1510_gettimeoffset;
gettimeoffset = omap_gettimeoffset;
timer_irq.handler = omap1510_timer_interrupt;
timer_irq.flags = SA_INTERRUPT;
#ifdef OMAP1510_USE_32KHZ_TIMER
timer32k_write(TIMER32k_CR, 0x0);
timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD);
setup_irq(INT_OS_32kHz_TIMER, &timer_irq);
setup_irq(INT_OS_32kHz_TIMER, &omap_timer_irq);
start_timer32k();
#else
setup_irq(INT_TIMER2, &timer_irq);
setup_irq(INT_TIMER2, &omap_timer_irq);
start_mputimer2(MPUTICKS_PER_SEC / 100 - 1);
#endif
}
#endif
......@@ -3,7 +3,7 @@
#
# Common support (must be linked before board specific support)
obj-y += generic.o irq.o dma.o
obj-y += generic.o irq.o dma.o time.o
obj-$(CONFIG_PXA25x) += pxa25x.o
obj-$(CONFIG_PXA27x) += pxa27x.o
......
......@@ -11,6 +11,7 @@
extern void __init pxa_map_io(void);
extern void __init pxa_init_irq(void);
extern void __init pxa_init_time(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
......
......@@ -118,5 +118,6 @@ MACHINE_START(PXA_IDP, "Accelent Xscale IDP")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(idp_map_io)
INITIRQ(idp_init_irq)
INITTIME(pxa_init_time)
INIT_MACHINE(idp_init)
MACHINE_END
......@@ -220,5 +220,6 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(lubbock_map_io)
INITIRQ(lubbock_init_irq)
INITTIME(pxa_init_time)
INIT_MACHINE(lubbock_init)
MACHINE_END
......@@ -137,5 +137,6 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(mainstone_map_io)
INITIRQ(mainstone_init_irq)
INITTIME(pxa_init_time)
INIT_MACHINE(mainstone_init)
MACHINE_END
/*
* linux/include/asm-arm/arch-pxa/time.h
* arch/arm/mach-pxa/time.c
*
* Author: Nicolas Pitre
* Created: Jun 15, 2001
......@@ -10,6 +10,24 @@
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
static inline unsigned long pxa_get_rtc_time(void)
{
......@@ -84,7 +102,13 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
void __init time_init(void)
static struct irqaction pxa_timer_irq = {
.name = "PXA Timer Tick",
.flags = SA_INTERRUPT,
.handler = pxa_timer_interrupt
};
void __init pxa_init_time(void)
{
struct timespec tv;
......@@ -95,10 +119,9 @@ void __init time_init(void)
tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = pxa_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &timer_irq);
setup_irq(IRQ_OST0, &pxa_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */
}
......
......@@ -14,6 +14,8 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/elf.h>
#include <asm/io.h>
......@@ -25,6 +27,7 @@
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
extern void rpc_init_irq(void);
......@@ -82,6 +85,33 @@ void __init rpc_map_io(void)
elf_hwcap &= ~HWCAP_HALF;
}
static irqreturn_t
rpc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
do_set_rtc();
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction rpc_timer_irq = {
.name = "RiscPC Timer Tick",
.flags = SA_INTERRUPT,
.handler = rpc_timer_interrupt
};
/*
* Set up timer interrupt.
*/
void __init rpc_init_time(void)
{
extern void ioctime_init(void);
ioctime_init();
setup_irq(IRQ_TIMER, &rpc_timer_irq);
}
MACHINE_START(RISCPC, "Acorn-RiscPC")
MAINTAINER("Russell King")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
......@@ -90,4 +120,5 @@ MACHINE_START(RISCPC, "Acorn-RiscPC")
DISABLE_PARPORT(1)
MAPIO(rpc_map_io)
INITIRQ(rpc_init_irq)
INITTIME(rpc_init_time)
MACHINE_END
......@@ -4,7 +4,7 @@
# Object file lists.
obj-y := s3c2410.o irq.o
obj-y := s3c2410.o irq.o time.o
obj-m :=
obj-n :=
obj- :=
......
......@@ -185,10 +185,16 @@ void __init bast_init_irq(void)
}
void __init bast_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(bast_map_io)
INITIRQ(bast_init_irq)
INITTIME(bast_init_time)
MACHINE_END
......@@ -91,10 +91,16 @@ void __init ipaq_init_irq(void)
}
void __init ipaq_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(H1940, "IPAQ-H1940")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(ipaq_map_io)
INITIRQ(ipaq_init_irq)
INITTIME(ipaq_init_time)
MACHINE_END
......@@ -99,6 +99,11 @@ void __init smdk2410_init_irq(void)
s3c2410_init_irq();
}
void __init smdk2410_init_time(void)
{
s3c2401_init_time();
}
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
MAINTAINER("Jonas Dietsche")
......@@ -106,4 +111,5 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(smdk2410_map_io)
INITIRQ(smdk2410_init_irq)
INITTIME(smdk2410_init_time)
MACHINE_END
......@@ -155,10 +155,16 @@ void __init vr1000_init_irq(void)
}
void __init vr1000_init_time(void)
{
s3c2401_init_time();
}
MACHINE_START(VR1000, "Simtec-VR1000")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(vr1000_map_io)
INITIRQ(vr1000_init_irq)
INITTIME(vr1000_init_time)
MACHINE_END
......@@ -4,3 +4,5 @@ extern void s3c2410_map_io(struct map_desc *, int count);
extern void s3c2410_init_irq(void);
extern s3c2410_init_time(void);
......@@ -18,15 +18,20 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/map.h>
#include <asm/arch/regs-timer.h>
extern unsigned long (*gettimeoffset)(void);
#include <asm/mach/time.h>
static unsigned long timer_startval;
static unsigned long timer_ticks_usec;
......@@ -79,15 +84,19 @@ s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
static struct irqaction s3c2410_timer_irq = {
.name = "S32410 Timer Tick",
.flags = SA_INTERRUPT,
.handler = s3c2410_timer_interrupt
};
/*
* Set up timer interrupt, and return the current time in seconds.
*/
/* currently we only use timer4, as it is the only timer which has no
*
* Currently we only use timer4, as it is the only timer which has no
* other function that can be exploited externally
*/
void __init time_init (void)
*/
void __init s3c2410_init_time (void)
{
unsigned long tcon;
unsigned long tcnt;
......@@ -95,7 +104,6 @@ void __init time_init (void)
unsigned long tcfg0;
gettimeoffset = s3c2410_gettimeoffset;
timer_irq.handler = s3c2410_timer_interrupt;
tcnt = 0xffff; /* default value for tcnt */
......@@ -161,7 +169,7 @@ void __init time_init (void)
__raw_writel(tcnt, S3C2410_TCNTB(4));
__raw_writel(tcnt, S3C2410_TCMPB(4));
setup_irq(IRQ_TIMER4, &timer_irq);
setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
/* start the timer running */
tcon |= S3C2410_TCON_T4START;
......
......@@ -147,4 +147,5 @@ MACHINE_START(ADSBITSY, "ADS Bitsy")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(adsbitsy_map_io)
INITIRQ(adsbitsy_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -324,5 +324,6 @@ MACHINE_START(ASSABET, "Intel-Assabet")
FIXUP(fixup_assabet)
MAPIO(assabet_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
INIT_MACHINE(assabet_init)
MACHINE_END
......@@ -245,4 +245,5 @@ MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
BOOT_PARAMS(0xc0000100)
MAPIO(badge4_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -37,4 +37,5 @@ MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(brutus_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -92,4 +92,5 @@ MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(cerf_map_io)
INITIRQ(cerf_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -35,4 +35,5 @@ MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(empeg_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -183,5 +183,6 @@ MACHINE_START(FLEXANET, "FlexaNet")
BOOT_PARAMS(0xc0000100)
MAPIO(flexanet_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -77,4 +77,5 @@ MACHINE_START(FREEBIRD, "Freebird-HPC-1.1")
#endif
MAPIO(freebird_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -6,6 +6,7 @@
extern void __init sa1100_map_io(void);
extern void __init sa1100_init_irq(void);
extern void __init sa1100_init_time(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
......
......@@ -198,4 +198,5 @@ MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsclient_map_io)
INITIRQ(graphicsclient_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -287,4 +287,5 @@ MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsmaster_map_io)
INITIRQ(graphicsmaster_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -286,6 +286,7 @@ MACHINE_START(H3100, "Compaq iPAQ H3100")
BOOT_PARAMS(0xc0000100)
MAPIO(h3100_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3100 */
......@@ -400,6 +401,7 @@ MACHINE_START(H3600, "Compaq iPAQ H3600")
BOOT_PARAMS(0xc0000100)
MAPIO(h3600_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3600 */
......@@ -783,6 +785,7 @@ MACHINE_START(H3800, "Compaq iPAQ H3800")
BOOT_PARAMS(0xc0000100)
MAPIO(h3800_map_io)
INITIRQ(h3800_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3800 */
......@@ -174,4 +174,5 @@ MACHINE_START(HACKKIT, "HackKit Cpu Board")
BOOT_PARAMS(0xc0000100)
MAPIO(hackkit_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -81,4 +81,5 @@ MACHINE_START(HUW_WEBPANEL, "HuW-Webpanel")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(huw_webpanel_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -37,4 +37,5 @@ MACHINE_START(ITSY, "Compaq Itsy")
BOOT_PARAMS(0xc0000100)
MAPIO(itsy_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -101,4 +101,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
BOOT_PARAMS(0xc0000100)
MAPIO(jornada720_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -43,4 +43,5 @@ MACHINE_START(LART, "LART")
BOOT_PARAMS(0xc0000100)
MAPIO(lart_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -49,4 +49,5 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine")
FIXUP(fixup_nanoengine)
MAPIO(nanoengine_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -59,4 +59,5 @@ MACHINE_START(OMNIMETER, "OmniMeter")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(omnimeter_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -40,4 +40,5 @@ MACHINE_START(PANGOLIN, "Dialogue-Pangolin")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pangolin_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -112,4 +112,5 @@ MACHINE_START(PFS168, "Tulsa")
BOOT_PARAMS(0xc0000100)
MAPIO(pfs168_map_io)
INITIRQ(pfs168_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -31,4 +31,5 @@ MACHINE_START(PLEB, "PLEB")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pleb_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -41,4 +41,5 @@ MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
BOOT_PARAMS(0xc0000100)
MAPIO(shannon_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -27,4 +27,5 @@ MACHINE_START(SHERMAN, "Blazie Engineering Sherman")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(sherman_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -231,4 +231,5 @@ MACHINE_START(SIMPAD, "Simpad")
BOOT_PARAMS(0xc0000100)
MAPIO(simpad_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -331,6 +331,7 @@ MACHINE_START(STORK, "Stork Technologies prototype")
BOOT_PARAMS(0xc0000100)
MAPIO(stork_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......
......@@ -470,4 +470,5 @@ MACHINE_START(PT_SYSTEM3, "PT System 3")
BOOT_PARAMS(0xc0000100)
MAPIO(system3_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -90,7 +90,13 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
void __init time_init(void)
static struct irqaction sa1100_timer_irq = {
.name = "SA11xx Timer Tick",
.flags = SA_INTERRUPT,
.handler = sa1100_timer_interrupt
};
void __init sa1100_init_time(void)
{
struct timespec tv;
......@@ -101,10 +107,9 @@ void __init time_init(void)
tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = sa1100_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &timer_irq);
setup_irq(IRQ_OST0, &sa1100_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */
}
......
......@@ -228,4 +228,5 @@ MACHINE_START(TRIZEPS, "TRIZEPS")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(trizeps_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -89,4 +89,5 @@ MACHINE_START(XP860, "XP860")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(xp860_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -91,4 +91,5 @@ MACHINE_START(YOPY, "Yopy")
BOOT_PARAMS(0xc0000100)
MAPIO(yopy_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
MACHINE_END
......@@ -5,13 +5,18 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/param.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
extern void shark_init_irq(void);
......@@ -24,10 +29,45 @@ static void __init shark_map_io(void)
iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
}
#define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ)
static irqreturn_t
shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction shark_timer_irq = {
.name = "Shark Timer Tick",
.flags = SA_INTERRUPT,
.handler = shark_timer_interrupt
};
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init shark_init_time(void)
{
unsigned long flags;
outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */
outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
outb(HZ_TIME >> 8, 0x40);
setup_irq(IRQ_TIMER, &shark_timer_irq);
}
MACHINE_START(SHARK, "Shark")
MAINTAINER("Alexander Schulz")
BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
BOOT_PARAMS(0x08003000)
MAPIO(shark_map_io)
INITIRQ(shark_init_irq)
INITTIME(shark_init_time)
MACHINE_END
......@@ -9,6 +9,8 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/elf.h>
#include <asm/setup.h>
......@@ -19,6 +21,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
extern unsigned long soft_irq_mask;
......@@ -64,10 +67,34 @@ static void __init tbox_map_io(void)
iotable_init(tbox_io_desc, ARRAY_SIZE(tbox_io_desc));
}
static irqreturn_t
tbox_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
/* Clear irq */
__raw_writel(1, FPGA1CONT + 0xc);
__raw_writel(0, FPGA1CONT + 0xc);
do_timer(regs);
return IRQ_HANDLED;
}
static struct irqaction tbox_timer_irq = {
.name = "TBOX Timer Tick",
.flags = SA_INTERRUPT,
.handler = tbox_timer_interrupt
};
void __init tbox_init_time(void)
{
setup_irq(IRQ_TIMER, &timer_irq);
}
MACHINE_START(TBOX, "unknown-TBOX")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x80000000, 0x00400000, 0xe0000000)
MAPIO(tbox_map_io)
INITIRQ(tbox_init_irq)
INITIME(tbox_init_time)
MACHINE_END
......@@ -22,7 +22,9 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
......@@ -33,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
#ifdef CONFIG_MMC
#include <asm/mach/mmc.h>
......@@ -511,11 +514,155 @@ static void __init versatile_init(void)
leds_event = versatile_leds_event;
}
/*
* Where is the timer (VA)?
*/
#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE)
/*
* How long is the timer interval?
*/
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
#if TIMER_INTERVAL >= 0x100000
#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */
#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */
#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
#elif TIMER_INTERVAL >= 0x10000
#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */
#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
#else
#define TIMER_RELOAD (TIMER_INTERVAL)
#define TIMER_CTRL 0x80 /* Enable */
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
/*
* What does it look like?
*/
typedef struct TimerStruct {
unsigned long TimerLoad;
unsigned long TimerValue;
unsigned long TimerControl;
unsigned long TimerClear;
} TimerStruct_t;
extern unsigned long (*gettimeoffset)(void);
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long versatile_gettimeoffset(void)
{
volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
unsigned long ticks1, ticks2, status;
/*
* Get the current number of ticks. Note that there is a race
* condition between us reading the timer and checking for
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
ticks2 = timer0->TimerValue & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
ticks2 = timer0->TimerValue & 0xffff;
} while (ticks2 > ticks1);
/*
* Number of ticks since last interrupt.
*/
ticks1 = TIMER_RELOAD - ticks2;
/*
* Interrupt pending? If so, we've reloaded once already.
*
* FIXME: Need to check this is effectively timer 0 that expires
*/
if (status & IRQMASK_TIMERINT0_1)
ticks1 += TIMER_RELOAD;
/*
* Convert the ticks to usecs
*/
return TICKS2USECS(ticks1);
}
/*
* IRQ handler for the timer
*/
static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
// ...clear the interrupt
timer0->TimerClear = 1;
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
static struct irqaction versatile_timer_irq = {
.name = "Versatile Timer Tick",
.flags = SA_INTERRUPT,
.handler = versatile_timer_interrupt
};
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init versatile_init_time(void)
{
volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
/*
* set clock frequency:
* VERSATILE_REFCLK is 32KHz
* VERSATILE_TIMCLK is 1MHz
*/
*(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |=
((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
(VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
/*
* Initialise to a known state (all timers off)
*/
timer0->TimerControl = 0;
timer1->TimerControl = 0;
timer2->TimerControl = 0;
timer3->TimerControl = 0;
timer0->TimerLoad = TIMER_RELOAD;
timer0->TimerValue = TIMER_RELOAD;
timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */
/*
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
gettimeoffset = versatile_gettimeoffset;
}
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
BOOT_PARAMS(0x00000100)
MAPIO(versatile_map_io)
INITIRQ(versatile_init_irq)
INITTIME(versatile_init_time)
INIT_MACHINE(versatile_init)
MACHINE_END
/*
* linux/include/asm-arm/arch-adifcc/time.h
*
*/
/*
* No on board timer, implementation @ arch/arm/kernel/xscale-time.c
*/
/*
* linux/include/asm-arm/arch-cl7500/time.h
*
* Copyright (c) 1996-2000 Russell King.
*
* Changelog:
* 24-Sep-1996 RMK Created
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
*/
extern void ioctime_init(void);
static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
do_set_rtc();
do_profile(regs);
{
/* Twinkle the lights. */
static int count, state = 0xff00;
if (count-- == 0) {
state ^= 0x100;
count = 25;
*((volatile unsigned int *)LED_ADDRESS) = state;
}
}
return IRQ_HANDLED;
}
/*
* Set up timer interrupt.
*/
void __init time_init(void)
{
ioctime_init();
timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq);
}
/*
* linux/include/asm-arm/arch-epxa10db/time.h
*
* Copyright (C) 2001 Altera Corporation
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/arch/hardware.h>
#define TIMER00_TYPE (volatile unsigned int*)
#include <asm/arch/timer00.h>
/*
* IRQ handler for the timer
*/
static irqreturn_t
excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
// ...clear the interrupt
*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init time_init(void)
{
timer_irq.handler = excalibur_timer_interrupt;
/*
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMER0, &timer_irq);
/* Start the timer */
*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
}
......@@ -457,6 +457,10 @@
#define mSEC_25 (mSEC_1 * 25)
#define SEC_1 (mSEC_1 * 1000)
#ifndef __ASSEMBLY__
extern void integrator_time_init(unsigned long, unsigned int);
#endif
#define INTEGRATOR_CSR_BASE 0x10000000
#define INTEGRATOR_CSR_SIZE 0x10000000
......
......@@ -58,6 +58,7 @@ struct ixp4xx_i2c_pins {
*/
extern void ixp4xx_map_io(void);
extern void ixp4xx_init_irq(void);
extern void ixp4xx_init_time(void);
extern void ixp4xx_pci_preinit(void);
struct pci_sys_data;
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
......
/*
* linux/include/asm-arm/arch-rpc/time.h
*
* Copyright (C) 1996-2000 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Changelog:
* 24-Sep-1996 RMK Created
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
*/
extern void ioctime_init(void);
static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
do_set_rtc();
do_profile(regs);
return IRQ_HANDLED;
}
/*
* Set up timer interrupt.
*/
void __init time_init(void)
{
ioctime_init();
timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq);
}
/*
* linux/include/asm-arm/arch-shark/time.h
*
* by Alexander Schulz
*
* derived from include/asm-arm/arch-ebsa110/time.h
* Copyright (c) 1996,1997,1998 Russell King.
*/
#include <asm/leds.h>
#include <asm/param.h>
#define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ)
static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_leds();
do_timer(regs);
do_profile(regs);
return IRQ_HANDLED;
}
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init time_init(void)
{
unsigned long flags;
outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */
outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
outb(HZ_TIME >> 8, 0x40);
timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq);
}
/*
* linux/include/asm-arm/arch-tbox/time.h
*
* Copyright (c) 1997, 1999 Phil Blundell.
* Copyright (c) 2000 FutureTV Labs Ltd
*
* Tbox has no real-time clock -- we get millisecond ticks to update
* our soft copy.
*/
/*
* 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 <asm/io.h>
#include <asm/hardware.h>
#define update_rtc()
static irqreturn_t
timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
/* Clear irq */
__raw_writel(1, FPGA1CONT + 0xc);
__raw_writel(0, FPGA1CONT + 0xc);
do_timer(regs);
return IRQ_HANDLED;
}
void __init time_init(void)
{
timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq);
}
......@@ -45,6 +45,8 @@ struct machine_desc {
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
void (*init_time)(void);
void (*gettimeoffset)(void);
void (*init_machine)(void);
};
......@@ -87,6 +89,9 @@ const struct machine_desc __mach_desc_##_type \
#define INITIRQ(_func) \
.init_irq = _func,
#define INITTIME(_func) \
.init_time = _func,
#define INIT_MACHINE(_func) \
.init_machine = _func,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment