aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/atheros/patches-2.6.28/100-board.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-03-22 18:33:08 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-03-22 18:33:08 +0000
commit3387cbae6318b9e030323a76da64a2951328e93b (patch)
tree1d01d7472908cc376880f236edf02b84e9fdff5f /target/linux/atheros/patches-2.6.28/100-board.patch
parentbb63dea4fb422d0009c2e701ffb9993f5086f987 (diff)
downloadupstream-3387cbae6318b9e030323a76da64a2951328e93b.tar.gz
upstream-3387cbae6318b9e030323a76da64a2951328e93b.tar.bz2
upstream-3387cbae6318b9e030323a76da64a2951328e93b.zip
atheros: fix gpio interrupt handling on 2315
SVN-Revision: 14973
Diffstat (limited to 'target/linux/atheros/patches-2.6.28/100-board.patch')
-rw-r--r--target/linux/atheros/patches-2.6.28/100-board.patch56
1 files changed, 33 insertions, 23 deletions
diff --git a/target/linux/atheros/patches-2.6.28/100-board.patch b/target/linux/atheros/patches-2.6.28/100-board.patch
index 2f7bb5b196..7c4fad1854 100644
--- a/target/linux/atheros/patches-2.6.28/100-board.patch
+++ b/target/linux/atheros/patches-2.6.28/100-board.patch
@@ -2096,7 +2096,7 @@
+
--- /dev/null
+++ b/arch/mips/ar231x/ar2315.c
-@@ -0,0 +1,663 @@
+@@ -0,0 +1,673 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
@@ -2142,22 +2142,24 @@
+static inline void ar2315_gpio_irq(void)
+{
+ u32 pend;
-+ int bit;
++ int bit = -1;
+
+ /* only do one gpio interrupt at a time */
+ pend = (ar231x_read_reg(AR2315_GPIO_DI) ^ gpiointval) & gpiointmask;
-+ if (!pend)
-+ return;
+
-+ bit = fls(pend);
-+ pend ^= (1 << bit);
-+ gpiointval ^= (1 << bit);
++ if (pend) {
++ bit = fls(pend) - 1;
++ printk("GPIO IRQ: pend=0x%08x, val=%08x, bit=%d\n", pend, gpiointval, bit);
++ pend &= ~(1 << bit);
++ gpiointval ^= (1 << bit);
++ printk("AFTER IRQ: pend=0x%08x, val=%08x, bit=%d\n", pend, gpiointval, bit);
++ }
+
-+ /* ACK the interrupt only if we handled all bits */
+ if (!pend)
-+ ar231x_write_reg(AR2315_ISR, ar231x_read_reg(AR2315_IMR) | ~AR2315_ISR_GPIO);
++ ar231x_write_reg(AR2315_ISR, AR2315_ISR_GPIO);
+
-+ do_IRQ(AR531X_GPIO_IRQ_BASE + fls(pend) - 1);
++ if (bit >= 0)
++ do_IRQ(AR531X_GPIO_IRQ_BASE + bit);
+}
+
+
@@ -2203,7 +2205,6 @@
+{
+ u32 reg;
+
-+
+ reg = ar231x_read_reg(AR2315_GPIO_INT);
+ reg &= ~(AR2315_GPIO_INT_M | AR2315_GPIO_INT_LVL_M);
+ reg |= gpio | AR2315_GPIO_INT_LVL(level);
@@ -2213,17 +2214,12 @@
+static void ar2315_gpio_intr_enable(unsigned int irq)
+{
+ unsigned int gpio = irq - AR531X_GPIO_IRQ_BASE;
-+ u32 reg;
-+
-+ gpiointmask &= ~(1 << gpio);
+
+ /* reconfigure GPIO line as input */
-+ reg = ar231x_read_reg(AR2315_GPIO_CR);
-+ reg &= ~(AR2315_GPIO_CR_M(gpio));
-+ reg |= AR2315_GPIO_CR_I(gpio);
-+ ar231x_write_reg(AR2315_GPIO_CR, reg);
++ ar231x_mask_reg(AR2315_GPIO_CR, AR2315_GPIO_CR_M(gpio), AR2315_GPIO_CR_I(gpio));
+
+ /* Enable interrupt with edge detection */
++ gpiointmask |= (1 << gpio);
+ ar2315_set_gpiointmask(gpio, 3);
+}
+
@@ -2231,19 +2227,33 @@
+{
+ unsigned int gpio = irq - AR531X_GPIO_IRQ_BASE;
+
-+ gpiointmask |= (1 << gpio);
-+
+ /* Disable interrupt */
++ gpiointmask &= ~(1 << gpio);
+ ar2315_set_gpiointmask(gpio, 0);
+}
+
++static unsigned int
++ar2315_gpio_intr_startup(unsigned int irq)
++{
++ ar2315_gpio_intr_enable(irq);
++ return 0;
++}
++
++static void
++ar2315_gpio_intr_end(unsigned int irq)
++{
++ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
++ ar2315_gpio_intr_enable(irq);
++}
++
+static struct irq_chip ar2315_gpio_intr_controller = {
+ .typename = "AR2315-GPIO",
++ .startup = ar2315_gpio_intr_startup,
++ .shutdown = ar2315_gpio_intr_disable,
++ .enable = ar2315_gpio_intr_enable,
+ .disable = ar2315_gpio_intr_disable,
+ .ack = ar2315_gpio_intr_disable,
-+ .mask_ack = ar2315_gpio_intr_disable,
-+ .unmask = ar2315_gpio_intr_enable,
-+ .eoi = ar2315_gpio_intr_enable,
++ .end = ar2315_gpio_intr_end,
+};
+
+static void