[ARM] 3946/1: AT91: at91_arch_reset and at91_extern_irq
authorAndrew Victor <andrew@sanpeople.com>
Thu, 30 Nov 2006 09:01:47 +0000 (10:01 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 30 Nov 2006 22:51:36 +0000 (22:51 +0000)
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>
arch/arm/mach-at91rm9200/at91rm9200.c
arch/arm/mach-at91rm9200/generic.h
arch/arm/mach-at91rm9200/irq.c
arch/arm/mach-at91rm9200/pm.c
include/asm-arm/arch-at91rm9200/system.h

index dcf6136fedf9deb51f916a190634e0c333d416c1..0422593032fc8b24b8bbb0cb39efc2068e8fb5ed 100644 (file)
@@ -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);
 
index 694e411e285f6933254ccbf077c2aa69c50a2237..fd98e353c5a2c23c86778b999402b4959fcfe536 100644 (file)
@@ -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;
index 3e488117ca91bb2154d992c9bd815d0d619750f2..2cea07a34a856d36281ea0b337edccf482c76dd5 100644 (file)
@@ -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;
index 32c95d8eaacf3dabe0866f9603104534b43839eb..5e3b6e306f1a3adea5baceccd5eed658c2087dd1 100644 (file)
@@ -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);
 
index 8a2ff472e4cff3e067dbaeb59f5695232c2109a0..1d54185e036d1e28c7b245ff8a4aed4cb634f5f8 100644 (file)
@@ -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