aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-dwapb.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2014-05-26 16:58:14 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-05-27 10:20:34 -0400
commit6a2f4b7dadd5e2b3e02e28af1ddb32d17ac5b310 (patch)
tree6ae3de8ba9ea5c4e91f0d92dc986561eb44502a3 /drivers/gpio/gpio-dwapb.c
parentc829f956f14b61cd6c390c5daced537613798239 (diff)
gpio: dwapb: use a second irq chip
Right new have one irq chip running always in level mode. It would nicer to have two irq chips where one is handling level type interrupts and the other one is doing edge interrupts. So we can have at runtime two users where one is using edge and the other level. Acked-by: Alan Tull <delicious.quinoa@gmail.com> Acked-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-dwapb.c')
-rw-r--r--drivers/gpio/gpio-dwapb.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 4d25a06bb45e..cd3b81435274 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -198,6 +198,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
198 break; 198 break;
199 } 199 }
200 200
201 irq_setup_alt_chip(d, type);
202
201 writel(level, gpio->regs + GPIO_INTTYPE_LEVEL); 203 writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
202 writel(polarity, gpio->regs + GPIO_INT_POLARITY); 204 writel(polarity, gpio->regs + GPIO_INT_POLARITY);
203 spin_unlock_irqrestore(&bgc->lock, flags); 205 spin_unlock_irqrestore(&bgc->lock, flags);
@@ -213,7 +215,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
213 struct irq_chip_generic *irq_gc; 215 struct irq_chip_generic *irq_gc;
214 unsigned int hwirq, ngpio = gc->ngpio; 216 unsigned int hwirq, ngpio = gc->ngpio;
215 struct irq_chip_type *ct; 217 struct irq_chip_type *ct;
216 int err, irq; 218 int err, irq, i;
217 219
218 irq = irq_of_parse_and_map(node, 0); 220 irq = irq_of_parse_and_map(node, 0);
219 if (!irq) { 221 if (!irq) {
@@ -227,7 +229,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
227 if (!gpio->domain) 229 if (!gpio->domain)
228 return; 230 return;
229 231
230 err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1, 232 err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2,
231 "gpio-dwapb", handle_level_irq, 233 "gpio-dwapb", handle_level_irq,
232 IRQ_NOREQUEST, 0, 234 IRQ_NOREQUEST, 0,
233 IRQ_GC_INIT_NESTED_LOCK); 235 IRQ_GC_INIT_NESTED_LOCK);
@@ -248,17 +250,24 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
248 irq_gc->reg_base = gpio->regs; 250 irq_gc->reg_base = gpio->regs;
249 irq_gc->private = gpio; 251 irq_gc->private = gpio;
250 252
251 ct = irq_gc->chip_types; 253 for (i = 0; i < 2; i++) {
252 ct->chip.irq_ack = irq_gc_ack_set_bit; 254 ct = &irq_gc->chip_types[i];
253 ct->chip.irq_mask = irq_gc_mask_set_bit; 255 ct->chip.irq_ack = irq_gc_ack_set_bit;
254 ct->chip.irq_unmask = irq_gc_mask_clr_bit; 256 ct->chip.irq_mask = irq_gc_mask_set_bit;
255 ct->chip.irq_set_type = dwapb_irq_set_type; 257 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
256 ct->chip.irq_enable = dwapb_irq_enable; 258 ct->chip.irq_set_type = dwapb_irq_set_type;
257 ct->chip.irq_disable = dwapb_irq_disable; 259 ct->chip.irq_enable = dwapb_irq_enable;
258 ct->chip.irq_request_resources = dwapb_irq_reqres; 260 ct->chip.irq_disable = dwapb_irq_disable;
259 ct->chip.irq_release_resources = dwapb_irq_relres; 261 ct->chip.irq_request_resources = dwapb_irq_reqres;
260 ct->regs.ack = GPIO_PORTA_EOI; 262 ct->chip.irq_release_resources = dwapb_irq_relres;
261 ct->regs.mask = GPIO_INTMASK; 263 ct->regs.ack = GPIO_PORTA_EOI;
264 ct->regs.mask = GPIO_INTMASK;
265 ct->type = IRQ_TYPE_LEVEL_MASK;
266 }
267
268 irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
269 irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
270 irq_gc->chip_types[1].handler = handle_edge_irq;
262 271
263 irq_set_chained_handler(irq, dwapb_irq_handler); 272 irq_set_chained_handler(irq, dwapb_irq_handler);
264 irq_set_handler_data(irq, gpio); 273 irq_set_handler_data(irq, gpio);