aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@marvell.com>2011-10-10 02:38:46 -0400
committerHaojian Zhuang <haojian.zhuang@marvell.com>2011-11-14 08:07:59 -0500
commit87c49e20579c933d531a376596875b8fd5dcb04f (patch)
treeda23de32023599ce92dbfb6a97887b91d2253a60
parent6384fdadb48a875bcc1c0f58933275f15f409b76 (diff)
ARM: pxa: use chained interrupt for GPIO0 and GPIO1
GPIO0 and GPIO1 are linked to unique interrupt line in PXA series, others are linked to another interrupt line. All GPIO are linked to one interrupt line in MMP series. Since gpio driver is shared between PXA series and MMP series, define GPIO0 and GPIO1 as chained interrupt chip. So we can move out gpio code from irq.c to gpio-pxa.c. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> Acked-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio.h15
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-pxa/irq.c58
-rw-r--r--drivers/gpio/gpio-pxa.c14
4 files changed, 16 insertions, 75 deletions
diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h
index 07fa3ba7a818..13b903907087 100644
--- a/arch/arm/mach-pxa/include/mach/gpio.h
+++ b/arch/arm/mach-pxa/include/mach/gpio.h
@@ -29,20 +29,7 @@
29#include "gpio-pxa.h" 29#include "gpio-pxa.h"
30 30
31#define gpio_to_irq(gpio) PXA_GPIO_TO_IRQ(gpio) 31#define gpio_to_irq(gpio) PXA_GPIO_TO_IRQ(gpio)
32 32#define irq_to_gpio(irq) (irq - PXA_GPIO_TO_IRQ(0))
33static inline int irq_to_gpio(unsigned int irq)
34{
35 int gpio;
36
37 if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1)
38 return irq - IRQ_GPIO0;
39
40 gpio = irq - PXA_GPIO_IRQ_BASE;
41 if (gpio >= 2 && gpio < NR_BUILTIN_GPIO)
42 return gpio;
43
44 return -1;
45}
46 33
47#include <plat/gpio.h> 34#include <plat/gpio.h>
48#endif 35#endif
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 1f996643b9de..b83d8ff4eae8 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -89,9 +89,7 @@
89 89
90#define PXA_GPIO_IRQ_BASE PXA_IRQ(96) 90#define PXA_GPIO_IRQ_BASE PXA_IRQ(96)
91#define PXA_GPIO_IRQ_NUM (192) 91#define PXA_GPIO_IRQ_NUM (192)
92 92#define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
93#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
94#define PXA_GPIO_TO_IRQ(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x))
95 93
96/* 94/*
97 * The following interrupts are for board specific purposes. Since 95 * The following interrupts are for board specific purposes. Since
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 532c5d3a97d2..36c538f48fa6 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -92,44 +92,6 @@ static struct irq_chip pxa_internal_irq_chip = {
92 .irq_unmask = pxa_unmask_irq, 92 .irq_unmask = pxa_unmask_irq,
93}; 93};
94 94
95/*
96 * GPIO IRQs for GPIO 0 and 1
97 */
98static int pxa_set_low_gpio_type(struct irq_data *d, unsigned int type)
99{
100 int gpio = d->irq - IRQ_GPIO0;
101
102 if (__gpio_is_occupied(gpio)) {
103 pr_err("%s failed: GPIO is configured\n", __func__);
104 return -EINVAL;
105 }
106
107 if (type & IRQ_TYPE_EDGE_RISING)
108 GRER0 |= GPIO_bit(gpio);
109 else
110 GRER0 &= ~GPIO_bit(gpio);
111
112 if (type & IRQ_TYPE_EDGE_FALLING)
113 GFER0 |= GPIO_bit(gpio);
114 else
115 GFER0 &= ~GPIO_bit(gpio);
116
117 return 0;
118}
119
120static void pxa_ack_low_gpio(struct irq_data *d)
121{
122 GEDR0 = (1 << (d->irq - IRQ_GPIO0));
123}
124
125static struct irq_chip pxa_low_gpio_chip = {
126 .name = "GPIO-l",
127 .irq_ack = pxa_ack_low_gpio,
128 .irq_mask = pxa_mask_irq,
129 .irq_unmask = pxa_unmask_irq,
130 .irq_set_type = pxa_set_low_gpio_type,
131};
132
133asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs) 95asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs)
134{ 96{
135 uint32_t icip, icmr, mask; 97 uint32_t icip, icmr, mask;
@@ -160,25 +122,6 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs)
160 } while (1); 122 } while (1);
161} 123}
162 124
163static void __init pxa_init_low_gpio_irq(set_wake_t fn)
164{
165 int irq;
166
167 /* clear edge detection on GPIO 0 and 1 */
168 GFER0 &= ~0x3;
169 GRER0 &= ~0x3;
170 GEDR0 = 0x3;
171
172 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
173 irq_set_chip_and_handler(irq, &pxa_low_gpio_chip,
174 handle_edge_irq);
175 irq_set_chip_data(irq, irq_base(0));
176 set_irq_flags(irq, IRQF_VALID);
177 }
178
179 pxa_low_gpio_chip.irq_set_wake = fn;
180}
181
182void __init pxa_init_irq(int irq_nr, set_wake_t fn) 125void __init pxa_init_irq(int irq_nr, set_wake_t fn)
183{ 126{
184 int irq, i, n; 127 int irq, i, n;
@@ -209,7 +152,6 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
209 __raw_writel(1, irq_base(0) + ICCR); 152 __raw_writel(1, irq_base(0) + ICCR);
210 153
211 pxa_internal_irq_chip.irq_set_wake = fn; 154 pxa_internal_irq_chip.irq_set_wake = fn;
212 pxa_init_low_gpio_irq(fn);
213} 155}
214 156
215#ifdef CONFIG_PM 157#ifdef CONFIG_PM
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index ee137712f9db..a4121bb50cf2 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -283,6 +283,20 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
283 __raw_writel(~0,c->regbase + GEDR_OFFSET); 283 __raw_writel(~0,c->regbase + GEDR_OFFSET);
284 } 284 }
285 285
286#ifdef CONFIG_ARCH_PXA
287 irq = gpio_to_irq(0);
288 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
289 handle_edge_irq);
290 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
291 irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
292
293 irq = gpio_to_irq(1);
294 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
295 handle_edge_irq);
296 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
297 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
298#endif
299
286 for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { 300 for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) {
287 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 301 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
288 handle_edge_irq); 302 handle_edge_irq);