aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>2015-04-07 06:43:45 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-04-08 10:41:59 -0400
commitb8a19382ac6212d18b21fcc7867060a5d54fe1a2 (patch)
tree1519fb351cafe47ef40fdf14125f570a220dc9cb
parent19ef697d1eb7be06dcd0d0eb170ee5cc206e8f84 (diff)
pinctrl: bcm2835: Fix support for threaded level triggered IRQs
Currently, the driver uses handle_simple_irq for all IRQ types and hard codes the acknowledge for different IRQ types into the handler. It is better to use the IRQ core as intended and let it handle the differences between the various types of IRQ. For example the current system does not work for threaded level triggered IRQs as these need to be masked until the threaded handler has run. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/bcm/pinctrl-bcm2835.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 4d08b850478e..8d908e3f42c3 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -403,15 +403,7 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id)
403 gpio = (32 * bank) + offset; 403 gpio = (32 * bank) + offset;
404 type = pc->irq_type[gpio]; 404 type = pc->irq_type[gpio];
405 405
406 /* ack edge triggered IRQs immediately */
407 if (!(type & IRQ_TYPE_LEVEL_MASK))
408 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
409
410 generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); 406 generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio));
411
412 /* ack level triggered IRQ after handling them */
413 if (type & IRQ_TYPE_LEVEL_MASK)
414 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
415 } 407 }
416 return events ? IRQ_HANDLED : IRQ_NONE; 408 return events ? IRQ_HANDLED : IRQ_NONE;
417} 409}
@@ -591,16 +583,32 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
591 else 583 else
592 ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type); 584 ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type);
593 585
586 if (type & IRQ_TYPE_EDGE_BOTH)
587 __irq_set_handler_locked(data->irq, handle_edge_irq);
588 else
589 __irq_set_handler_locked(data->irq, handle_level_irq);
590
594 spin_unlock_irqrestore(&pc->irq_lock[bank], flags); 591 spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
595 592
596 return ret; 593 return ret;
597} 594}
598 595
596static void bcm2835_gpio_irq_ack(struct irq_data *data)
597{
598 struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
599 unsigned gpio = irqd_to_hwirq(data);
600
601 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
602}
603
599static struct irq_chip bcm2835_gpio_irq_chip = { 604static struct irq_chip bcm2835_gpio_irq_chip = {
600 .name = MODULE_NAME, 605 .name = MODULE_NAME,
601 .irq_enable = bcm2835_gpio_irq_enable, 606 .irq_enable = bcm2835_gpio_irq_enable,
602 .irq_disable = bcm2835_gpio_irq_disable, 607 .irq_disable = bcm2835_gpio_irq_disable,
603 .irq_set_type = bcm2835_gpio_irq_set_type, 608 .irq_set_type = bcm2835_gpio_irq_set_type,
609 .irq_ack = bcm2835_gpio_irq_ack,
610 .irq_mask = bcm2835_gpio_irq_disable,
611 .irq_unmask = bcm2835_gpio_irq_enable,
604}; 612};
605 613
606static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) 614static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
@@ -977,7 +985,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
977 int irq = irq_create_mapping(pc->irq_domain, i); 985 int irq = irq_create_mapping(pc->irq_domain, i);
978 irq_set_lockdep_class(irq, &gpio_lock_class); 986 irq_set_lockdep_class(irq, &gpio_lock_class);
979 irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip, 987 irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip,
980 handle_simple_irq); 988 handle_level_irq);
981 irq_set_chip_data(irq, pc); 989 irq_set_chip_data(irq, pc);
982 set_irq_flags(irq, IRQF_VALID); 990 set_irq_flags(irq, IRQF_VALID);
983 } 991 }