From a1f4a3dd0592ef982017a50a7cfe749823114203 Mon Sep 17 00:00:00 2001 From: wdenk Date: Sun, 11 Jul 2004 22:19:26 +0000 Subject: * Patch by George G. Davis, 06 Jul 2004: - update mach-types.h to latest arm.linux.org.uk master list - Set correct OMAP1610 bi_arch_number for build target * Patch by Curt Brune, 06 Jul 2004: evb4510: add support for timer interrupt; cleanup --- cpu/arm720t/interrupts.c | 121 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 91 insertions(+), 30 deletions(-) (limited to 'cpu') diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c index 485443f..842a443 100644 --- a/cpu/arm720t/interrupts.c +++ b/cpu/arm720t/interrupts.c @@ -46,6 +46,15 @@ extern void reset_cpu(ulong addr); #define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK) #endif +#ifdef CONFIG_S3C4510B +/* require interrupts for the S3C4510B */ +# ifndef CONFIG_USE_IRQ +# error CONFIG_USE_IRQ _must_ be defined when using CONFIG_S3C4510B +# else +static struct _irq_handler IRQ_HANDLER[N_IRQS]; +# endif +#endif /* CONFIG_S3C4510B */ + #ifdef CONFIG_USE_IRQ /* enable IRQ/FIQ interrupts */ void enable_interrupts (void) @@ -75,7 +84,7 @@ int disable_interrupts (void) : "memory"); return (old & 0x80) == 0; } -#else +#else /* CONFIG_USE_IRQ */ void enable_interrupts (void) { return; @@ -86,7 +95,6 @@ int disable_interrupts (void) } #endif - void bad_mode (void) { panic ("Resetting CPU ...\n"); @@ -174,11 +182,42 @@ void do_fiq (struct pt_regs *pt_regs) void do_irq (struct pt_regs *pt_regs) { +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) printf ("interrupt request\n"); show_regs (pt_regs); bad_mode (); +#elif defined(CONFIG_S3C4510B) + unsigned int pending; + + while ( (pending = GET_REG( REG_INTOFFSET)) != 0x54) { /* sentinal value for no pending interrutps */ + IRQ_HANDLER[pending>>2].m_func( IRQ_HANDLER[pending>>2].m_data); + + /* clear pending interrupt */ + PUT_REG( REG_INTPEND, (1<<(pending>>2))); + } +#else +#error do_irq() not defined for this CPU type +#endif +} + + +#ifdef CONFIG_S3C4510B +static void default_isr( void *data) { + printf ("default_isr(): called for IRQ %d\n", (int)data); } +static void timer_isr( void *data) { + unsigned int *pTime = (unsigned int *)data; + + (*pTime)++; + if ( !(*pTime % (CFG_HZ/4))) { + /* toggle LED 0 */ + PUT_REG( REG_IOPDATA, GET_REG(REG_IOPDATA) ^ 0x1); + } + +} +#endif + static ulong timestamp; static ulong lastdec; @@ -209,8 +248,48 @@ int interrupt_init (void) /* set timer 1 counter */ lastdec = IO_TC1D = TIMER_LOAD_VAL; #elif defined(CONFIG_S3C4510B) - /* Nothing to do, interrupts not supported */ + int i; + + /* install default interrupt handlers */ + for ( i = 0; i < N_IRQS; i++) { + IRQ_HANDLER[i].m_data = (void *)i; + IRQ_HANDLER[i].m_func = default_isr; + } + + /* configure interrupts for IRQ mode */ + PUT_REG( REG_INTMODE, 0x0); + /* clear any pending interrupts */ + PUT_REG( REG_INTPEND, 0x1FFFFF); + lastdec = 0; + + /* install interrupt handler for timer */ + IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; + IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; + + /* configure free running timer 0 */ + PUT_REG( REG_TMOD, 0x0); + /* Stop timer 0 */ + CLR_REG( REG_TMOD, TM0_RUN); + + /* Configure for interval mode */ + CLR_REG( REG_TMOD, TM1_TOGGLE); + + /* + * Load Timer data register with count down value. + * count_down_val = CFG_SYS_CLK_FREQ/CFG_HZ + */ + PUT_REG( REG_TDATA0, (CFG_SYS_CLK_FREQ / CFG_HZ)); + + /* + * Enable global interrupt + * Enable timer0 interrupt + */ + CLR_REG( REG_INTMASK, ((1< TMR_OFFSET); - - /* Stop timer */ - CLR_REG( REG_TMOD, TM0_RUN); - -} + while (get_timer (0) < ticks) + /*NOP*/; -ulong get_timer (ulong base) -{ - return (0xFFFFFFFF - GET_REG( REG_TCNT1)) - base; } #else -- cgit v1.1