diff options
Diffstat (limited to 'arch/arm/mach-pxa/irq.c')
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index fa69c3a6a38e..d3d40a31f9da 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
22 | #include <asm/mach/irq.h> | 22 | #include <asm/mach/irq.h> |
23 | #include <mach/pxa-regs.h> | 23 | #include <mach/pxa-regs.h> |
24 | #include <mach/gpio.h> | ||
24 | 25 | ||
25 | #include "generic.h" | 26 | #include "generic.h" |
26 | 27 | ||
@@ -51,6 +52,72 @@ static struct irq_chip pxa_internal_irq_chip = { | |||
51 | .unmask = pxa_unmask_irq, | 52 | .unmask = pxa_unmask_irq, |
52 | }; | 53 | }; |
53 | 54 | ||
55 | /* | ||
56 | * GPIO IRQs for GPIO 0 and 1 | ||
57 | */ | ||
58 | static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type) | ||
59 | { | ||
60 | int gpio = irq - IRQ_GPIO0; | ||
61 | |||
62 | if (__gpio_is_occupied(gpio)) { | ||
63 | pr_err("%s failed: GPIO is configured\n", __func__); | ||
64 | return -EINVAL; | ||
65 | } | ||
66 | |||
67 | if (type & IRQ_TYPE_EDGE_RISING) | ||
68 | GRER0 |= GPIO_bit(gpio); | ||
69 | else | ||
70 | GRER0 &= ~GPIO_bit(gpio); | ||
71 | |||
72 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
73 | GFER0 |= GPIO_bit(gpio); | ||
74 | else | ||
75 | GFER0 &= ~GPIO_bit(gpio); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static void pxa_ack_low_gpio(unsigned int irq) | ||
81 | { | ||
82 | GEDR0 = (1 << (irq - IRQ_GPIO0)); | ||
83 | } | ||
84 | |||
85 | static void pxa_mask_low_gpio(unsigned int irq) | ||
86 | { | ||
87 | ICMR &= ~(1 << (irq - PXA_IRQ(0))); | ||
88 | } | ||
89 | |||
90 | static void pxa_unmask_low_gpio(unsigned int irq) | ||
91 | { | ||
92 | ICMR |= 1 << (irq - PXA_IRQ(0)); | ||
93 | } | ||
94 | |||
95 | static struct irq_chip pxa_low_gpio_chip = { | ||
96 | .name = "GPIO-l", | ||
97 | .ack = pxa_ack_low_gpio, | ||
98 | .mask = pxa_mask_low_gpio, | ||
99 | .unmask = pxa_unmask_low_gpio, | ||
100 | .set_type = pxa_set_low_gpio_type, | ||
101 | }; | ||
102 | |||
103 | static void __init pxa_init_low_gpio_irq(set_wake_t fn) | ||
104 | { | ||
105 | int irq; | ||
106 | |||
107 | /* clear edge detection on GPIO 0 and 1 */ | ||
108 | GFER0 &= ~0x3; | ||
109 | GRER0 &= ~0x3; | ||
110 | GEDR0 = 0x3; | ||
111 | |||
112 | for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { | ||
113 | set_irq_chip(irq, &pxa_low_gpio_chip); | ||
114 | set_irq_handler(irq, handle_edge_irq); | ||
115 | set_irq_flags(irq, IRQF_VALID); | ||
116 | } | ||
117 | |||
118 | pxa_low_gpio_chip.set_wake = fn; | ||
119 | } | ||
120 | |||
54 | void __init pxa_init_irq(int irq_nr, set_wake_t fn) | 121 | void __init pxa_init_irq(int irq_nr, set_wake_t fn) |
55 | { | 122 | { |
56 | int irq; | 123 | int irq; |
@@ -72,6 +139,7 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn) | |||
72 | } | 139 | } |
73 | 140 | ||
74 | pxa_internal_irq_chip.set_wake = fn; | 141 | pxa_internal_irq_chip.set_wake = fn; |
142 | pxa_init_low_gpio_irq(fn); | ||
75 | } | 143 | } |
76 | 144 | ||
77 | #ifdef CONFIG_PM | 145 | #ifdef CONFIG_PM |