Commit 1f4fd0a0 authored by Andrew Victor's avatar Andrew Victor Committed by Russell King

[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: default avatarAndrew Victor <andrew@sanpeople.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 20127f68
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/arch/at91rm9200.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include "generic.h" #include "generic.h"
...@@ -222,6 +223,16 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { ...@@ -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 * AT91RM9200 processor initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -230,6 +241,12 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks ...@@ -230,6 +241,12 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks
/* Map peripherals */ /* Map peripherals */
iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); 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 */ /* Init clock subsystem */
at91_clock_init(main_clock); at91_clock_init(main_clock);
......
...@@ -39,3 +39,6 @@ struct at91_gpio_bank { ...@@ -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_init(struct at91_gpio_bank *, int nr_banks);
extern void __init at91_gpio_irq_setup(void); extern void __init at91_gpio_irq_setup(void);
extern void (*at91_arch_reset)(void);
extern int at91_extern_irq;
...@@ -47,6 +47,10 @@ static void at91_aic_unmask_irq(unsigned int irq) ...@@ -47,6 +47,10 @@ static void at91_aic_unmask_irq(unsigned int irq)
at91_sys_write(AT91_AIC_IECR, 1 << 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) static int at91_aic_set_type(unsigned irq, unsigned type)
{ {
unsigned int smr, srctype; unsigned int smr, srctype;
...@@ -59,14 +63,16 @@ static int at91_aic_set_type(unsigned irq, unsigned type) ...@@ -59,14 +63,16 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
srctype = AT91_AIC_SRCTYPE_RISING; srctype = AT91_AIC_SRCTYPE_RISING;
break; break;
case IRQT_LOW: 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; return -EINVAL;
srctype = AT91_AIC_SRCTYPE_LOW;
break; break;
case IRQT_FALLING: 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; return -EINVAL;
srctype = AT91_AIC_SRCTYPE_FALLING;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -112,7 +112,6 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock); ...@@ -112,7 +112,6 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
static void (*slow_clock)(void); static void (*slow_clock)(void);
static int at91_pm_enter(suspend_state_t state) static int at91_pm_enter(suspend_state_t state)
{ {
at91_gpio_suspend(); at91_gpio_suspend();
...@@ -123,13 +122,7 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -123,13 +122,7 @@ static int at91_pm_enter(suspend_state_t state)
(at91_sys_read(AT91_PMC_PCSR) (at91_sys_read(AT91_PMC_PCSR)
| (1 << AT91_ID_FIQ) | (1 << AT91_ID_FIQ)
| (1 << AT91_ID_SYS) | (1 << AT91_ID_SYS)
| (1 << AT91RM9200_ID_IRQ0) | (at91_extern_irq))
| (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_sys_read(AT91_AIC_IMR), & at91_sys_read(AT91_AIC_IMR),
state); state);
......
...@@ -39,13 +39,15 @@ static inline void arch_idle(void) ...@@ -39,13 +39,15 @@ static inline void arch_idle(void)
cpu_do_idle(); cpu_do_idle();
} }
void (*at91_arch_reset)(void);
static inline void arch_reset(char mode) static inline void arch_reset(char mode)
{ {
/* /* call the CPU-specific reset function */
* Perform a hardware reset with the use of the Watchdog timer. if (at91_arch_reset)
*/ (at91_arch_reset)();
at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); for (;;) {} /* wait fovever */
} }
#define ARCH_ID_AT91RM9200 0x09200080 #define ARCH_ID_AT91RM9200 0x09200080
......
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