diff options
Diffstat (limited to 'arch/arm/mach-ep93xx/gpio.c')
-rw-r--r-- | arch/arm/mach-ep93xx/gpio.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index 34e071d79761..a5a9ff70b198 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c | |||
@@ -101,7 +101,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
101 | static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) | 101 | static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) |
102 | { | 102 | { |
103 | /* | 103 | /* |
104 | * map discontiguous hw irq range to continous sw irq range: | 104 | * map discontiguous hw irq range to continuous sw irq range: |
105 | * | 105 | * |
106 | * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) | 106 | * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) |
107 | */ | 107 | */ |
@@ -117,7 +117,7 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d) | |||
117 | int port = line >> 3; | 117 | int port = line >> 3; |
118 | int port_mask = 1 << (line & 7); | 118 | int port_mask = 1 << (line & 7); |
119 | 119 | ||
120 | if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { | 120 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { |
121 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | 121 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ |
122 | ep93xx_gpio_update_int_params(port); | 122 | ep93xx_gpio_update_int_params(port); |
123 | } | 123 | } |
@@ -131,7 +131,7 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) | |||
131 | int port = line >> 3; | 131 | int port = line >> 3; |
132 | int port_mask = 1 << (line & 7); | 132 | int port_mask = 1 << (line & 7); |
133 | 133 | ||
134 | if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | 134 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) |
135 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | 135 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ |
136 | 136 | ||
137 | gpio_int_unmasked[port] &= ~port_mask; | 137 | gpio_int_unmasked[port] &= ~port_mask; |
@@ -165,10 +165,10 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d) | |||
165 | */ | 165 | */ |
166 | static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) | 166 | static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) |
167 | { | 167 | { |
168 | struct irq_desc *desc = irq_desc + d->irq; | ||
169 | const int gpio = irq_to_gpio(d->irq); | 168 | const int gpio = irq_to_gpio(d->irq); |
170 | const int port = gpio >> 3; | 169 | const int port = gpio >> 3; |
171 | const int port_mask = 1 << (gpio & 7); | 170 | const int port_mask = 1 << (gpio & 7); |
171 | irq_flow_handler_t handler; | ||
172 | 172 | ||
173 | gpio_direction_input(gpio); | 173 | gpio_direction_input(gpio); |
174 | 174 | ||
@@ -176,22 +176,22 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
176 | case IRQ_TYPE_EDGE_RISING: | 176 | case IRQ_TYPE_EDGE_RISING: |
177 | gpio_int_type1[port] |= port_mask; | 177 | gpio_int_type1[port] |= port_mask; |
178 | gpio_int_type2[port] |= port_mask; | 178 | gpio_int_type2[port] |= port_mask; |
179 | desc->handle_irq = handle_edge_irq; | 179 | handler = handle_edge_irq; |
180 | break; | 180 | break; |
181 | case IRQ_TYPE_EDGE_FALLING: | 181 | case IRQ_TYPE_EDGE_FALLING: |
182 | gpio_int_type1[port] |= port_mask; | 182 | gpio_int_type1[port] |= port_mask; |
183 | gpio_int_type2[port] &= ~port_mask; | 183 | gpio_int_type2[port] &= ~port_mask; |
184 | desc->handle_irq = handle_edge_irq; | 184 | handler = handle_edge_irq; |
185 | break; | 185 | break; |
186 | case IRQ_TYPE_LEVEL_HIGH: | 186 | case IRQ_TYPE_LEVEL_HIGH: |
187 | gpio_int_type1[port] &= ~port_mask; | 187 | gpio_int_type1[port] &= ~port_mask; |
188 | gpio_int_type2[port] |= port_mask; | 188 | gpio_int_type2[port] |= port_mask; |
189 | desc->handle_irq = handle_level_irq; | 189 | handler = handle_level_irq; |
190 | break; | 190 | break; |
191 | case IRQ_TYPE_LEVEL_LOW: | 191 | case IRQ_TYPE_LEVEL_LOW: |
192 | gpio_int_type1[port] &= ~port_mask; | 192 | gpio_int_type1[port] &= ~port_mask; |
193 | gpio_int_type2[port] &= ~port_mask; | 193 | gpio_int_type2[port] &= ~port_mask; |
194 | desc->handle_irq = handle_level_irq; | 194 | handler = handle_level_irq; |
195 | break; | 195 | break; |
196 | case IRQ_TYPE_EDGE_BOTH: | 196 | case IRQ_TYPE_EDGE_BOTH: |
197 | gpio_int_type1[port] |= port_mask; | 197 | gpio_int_type1[port] |= port_mask; |
@@ -200,17 +200,16 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
200 | gpio_int_type2[port] &= ~port_mask; /* falling */ | 200 | gpio_int_type2[port] &= ~port_mask; /* falling */ |
201 | else | 201 | else |
202 | gpio_int_type2[port] |= port_mask; /* rising */ | 202 | gpio_int_type2[port] |= port_mask; /* rising */ |
203 | desc->handle_irq = handle_edge_irq; | 203 | handler = handle_edge_irq; |
204 | break; | 204 | break; |
205 | default: | 205 | default: |
206 | pr_err("failed to set irq type %d for gpio %d\n", type, gpio); | 206 | pr_err("failed to set irq type %d for gpio %d\n", type, gpio); |
207 | return -EINVAL; | 207 | return -EINVAL; |
208 | } | 208 | } |
209 | 209 | ||
210 | gpio_int_enabled[port] |= port_mask; | 210 | __irq_set_handler_locked(d->irq, handler); |
211 | 211 | ||
212 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 212 | gpio_int_enabled[port] |= port_mask; |
213 | desc->status |= type & IRQ_TYPE_SENSE_MASK; | ||
214 | 213 | ||
215 | ep93xx_gpio_update_int_params(port); | 214 | ep93xx_gpio_update_int_params(port); |
216 | 215 | ||
@@ -232,20 +231,29 @@ void __init ep93xx_gpio_init_irq(void) | |||
232 | 231 | ||
233 | for (gpio_irq = gpio_to_irq(0); | 232 | for (gpio_irq = gpio_to_irq(0); |
234 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { | 233 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { |
235 | set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip); | 234 | irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, |
236 | set_irq_handler(gpio_irq, handle_level_irq); | 235 | handle_level_irq); |
237 | set_irq_flags(gpio_irq, IRQF_VALID); | 236 | set_irq_flags(gpio_irq, IRQF_VALID); |
238 | } | 237 | } |
239 | 238 | ||
240 | set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); | 239 | irq_set_chained_handler(IRQ_EP93XX_GPIO_AB, |
241 | set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler); | 240 | ep93xx_gpio_ab_irq_handler); |
242 | set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler); | 241 | irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX, |
243 | set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler); | 242 | ep93xx_gpio_f_irq_handler); |
244 | set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler); | 243 | irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX, |
245 | set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler); | 244 | ep93xx_gpio_f_irq_handler); |
246 | set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler); | 245 | irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX, |
247 | set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler); | 246 | ep93xx_gpio_f_irq_handler); |
248 | set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler); | 247 | irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX, |
248 | ep93xx_gpio_f_irq_handler); | ||
249 | irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX, | ||
250 | ep93xx_gpio_f_irq_handler); | ||
251 | irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX, | ||
252 | ep93xx_gpio_f_irq_handler); | ||
253 | irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX, | ||
254 | ep93xx_gpio_f_irq_handler); | ||
255 | irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX, | ||
256 | ep93xx_gpio_f_irq_handler); | ||
249 | } | 257 | } |
250 | 258 | ||
251 | 259 | ||