diff options
author | Andrew Victor <andrew@sanpeople.com> | 2006-11-30 10:01:47 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-11-30 22:51:36 +0000 |
commit | 1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6 (patch) | |
tree | 09562e8467136cf545b5631a257a0e9d53a31a89 | |
parent | 20127f6863990e1313178debe8c9cfe32d43b1dc (diff) | |
download | linux-3.10-1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6.tar.gz linux-3.10-1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6.tar.bz2 linux-3.10-1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6.zip |
[ARM] 3946/1: AT91: at91_arch_reset and at91_extern_irq
The external interrupt sources are different on the various AT91
processors. This patch introduces the global 'at91_extern_irq' variable
that contains a bitset of the available external interrupt sources.
The processor reset mechanism also differs on the various AT91
processors. This patch also adds a global 'at91_arch_reset' callback
(from system.h) into the processor-specific code to perform the reset.
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mach-at91rm9200/at91rm9200.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-at91rm9200/generic.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-at91rm9200/irq.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-at91rm9200/pm.c | 9 | ||||
-rw-r--r-- | include/asm-arm/arch-at91rm9200/system.h | 12 |
5 files changed, 38 insertions, 17 deletions
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index dcf6136fedf..0422593032f 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -14,6 +14,7 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/arch/at91rm9200.h> #include <asm/hardware.h> #include "generic.h" @@ -222,6 +223,16 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; +static void at91rm9200_reset(void) +{ + /* + * Perform a hardware reset with the use of the Watchdog timer. + */ + at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + + /* -------------------------------------------------------------------- * AT91RM9200 processor initialization * -------------------------------------------------------------------- */ @@ -230,6 +241,12 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks /* Map peripherals */ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); + at91_arch_reset = at91rm9200_reset; + at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) + | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) + | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) + | (1 << AT91RM9200_ID_IRQ6); + /* Init clock subsystem */ at91_clock_init(main_clock); diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index 694e411e285..fd98e353c5a 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -39,3 +39,6 @@ struct at91_gpio_bank { }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); + +extern void (*at91_arch_reset)(void); +extern int at91_extern_irq; diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index 3e488117ca9..2cea07a34a8 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -47,6 +47,10 @@ static void at91_aic_unmask_irq(unsigned int irq) at91_sys_write(AT91_AIC_IECR, 1 << irq); } +unsigned int at91_extern_irq; + +#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) + static int at91_aic_set_type(unsigned irq, unsigned type) { unsigned int smr, srctype; @@ -59,14 +63,16 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQT_LOW: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_FALLING; break; default: return -EINVAL; diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 32c95d8eaac..5e3b6e306f1 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -112,7 +112,6 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock); static void (*slow_clock)(void); - static int at91_pm_enter(suspend_state_t state) { at91_gpio_suspend(); @@ -123,13 +122,7 @@ static int at91_pm_enter(suspend_state_t state) (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) - | (1 << AT91RM9200_ID_IRQ0) - | (1 << AT91RM9200_ID_IRQ1) - | (1 << AT91RM9200_ID_IRQ2) - | (1 << AT91RM9200_ID_IRQ3) - | (1 << AT91RM9200_ID_IRQ4) - | (1 << AT91RM9200_ID_IRQ5) - | (1 << AT91RM9200_ID_IRQ6)) + | (at91_extern_irq)) & at91_sys_read(AT91_AIC_IMR), state); diff --git a/include/asm-arm/arch-at91rm9200/system.h b/include/asm-arm/arch-at91rm9200/system.h index 8a2ff472e4c..1d54185e036 100644 --- a/include/asm-arm/arch-at91rm9200/system.h +++ b/include/asm-arm/arch-at91rm9200/system.h @@ -39,13 +39,15 @@ static inline void arch_idle(void) cpu_do_idle(); } +void (*at91_arch_reset)(void); + static inline void arch_reset(char mode) { - /* - * Perform a hardware reset with the use of the Watchdog timer. - */ - at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); + /* call the CPU-specific reset function */ + if (at91_arch_reset) + (at91_arch_reset)(); + + for (;;) {} /* wait fovever */ } #define ARCH_ID_AT91RM9200 0x09200080 |