patch-2.4.19 linux-2.4.19/arch/arm/mach-sa1100/irq.c

Next file: linux-2.4.19/arch/arm/mach-sa1100/itsy.c
Previous file: linux-2.4.19/arch/arm/mach-sa1100/huw_webpanel.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/arm/mach-sa1100/irq.c linux-2.4.19/arch/arm/mach-sa1100/irq.c
@@ -9,12 +9,11 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <linux/ptrace.h>
 
 #include <asm/hardware.h>
@@ -35,8 +34,13 @@
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
 
-void set_GPIO_IRQ_edge( int gpio_mask, int edge )
+void set_GPIO_IRQ_edge(int gpio_mask, int edge)
 {
+	long flags;
+	int irq = 0;
+
+	gpio_mask &= 0x0fffffff;
+	local_irq_save(flags);
 	if (edge & GPIO_FALLING_EDGE)
 		GPIO_IRQ_falling_edge |= gpio_mask;
 	else
@@ -45,6 +49,17 @@
 		GPIO_IRQ_rising_edge |= gpio_mask;
 	else
 		GPIO_IRQ_rising_edge &= ~gpio_mask;
+	GPDR &= ~gpio_mask;
+	GAFR &= ~gpio_mask;
+	while (gpio_mask) {
+		if (irq == 11)
+			irq = IRQ_GPIO11;
+		if (gpio_mask & 1)
+			irq_desc[irq].valid = 1;
+		irq++;
+		gpio_mask >>= 1;
+	}
+	local_irq_restore(flags);
 }
 
 EXPORT_SYMBOL(set_GPIO_IRQ_edge);
@@ -121,7 +136,7 @@
 
 		for (i = 11; i <= 27; ++i) {
 			if (irq & (1<<i)) {
-				do_IRQ (IRQ_GPIO_11_27(i), regs);
+				do_IRQ(IRQ_GPIO11 + i - 11, regs);
 			}
 		}
 	}
@@ -175,11 +190,18 @@
 	GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
 }
 
+static struct resource irq_resource = {
+	name:	"irqs",
+	start:	0x90050000,
+	end:	0x9005ffff,
+};
 
 void __init sa1100_init_irq(void)
 {
 	int irq;
 
+	request_resource(&iomem_resource, &irq_resource);
+
 	/* disable all IRQs */
 	ICMR = 0;
 
@@ -197,8 +219,13 @@
 	 */
 	ICCR = 1;
 
+	/*
+	 * Note: GPIO IRQs are initially invalid until at least one call
+	 * to set_GPIO_IRQ_edge() is performed.
+	 */
+
 	for (irq = 0; irq <= 10; irq++) {
-		irq_desc[irq].valid	= 1;
+		irq_desc[irq].valid	= 0;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= sa1100_mask_and_ack_GPIO0_10_irq;
 		irq_desc[irq].mask	= sa1100_mask_GPIO0_10_irq;
@@ -214,7 +241,7 @@
 	}
 
 	for (irq = 32; irq <= 48; irq++) {
-		irq_desc[irq].valid	= 1;
+		irq_desc[irq].valid	= 0;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= sa1100_mask_and_ack_GPIO11_27_irq;
 		irq_desc[irq].mask	= sa1100_mask_GPIO11_27_irq;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)