Skip to content

Commit

Permalink
pinctrl: bcm2835: Pass irqchip when adding gpiochip
Browse files Browse the repository at this point in the history
We need to convert all old gpio irqchips to pass the irqchip
setup along when adding the gpio_chip. For more info see
drivers/gpio/TODO.

For chained irqchips this is a pretty straight-forward
conversion. The BCM2835 has multiple parents so let's
exploit the new facility in the GPIO_IRQCHIP to actually
deal with multiple parents.

Cc: Eric Anholt <eric@anholt.net>
Cc: Thierry Reding <treding@nvidia.com>
[Rebased on changes in the pinctrl tree]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Link: https://lore.kernel.org/r/20190812062729.1892-1-linus.walleij@linaro.org
  • Loading branch information
Linus Walleij committed Aug 26, 2019
1 parent 7c772be commit 73345a1
Showing 1 changed file with 25 additions and 30 deletions.
55 changes: 25 additions & 30 deletions drivers/pinctrl/bcm/pinctrl-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
struct bcm2835_pinctrl {
struct device *dev;
void __iomem *base;
int irq[BCM2835_NUM_IRQS];

/* note: locking assumes each bank will have its own unsigned long */
unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
Expand Down Expand Up @@ -382,14 +381,14 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
int group;
int i;

for (i = 0; i < ARRAY_SIZE(pc->irq); i++) {
if (pc->irq[i] == irq) {
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
if (chip->irq.parents[i] == irq) {
group = i;
break;
}
}
/* This should not happen, every IRQ has a bank */
if (i == ARRAY_SIZE(pc->irq))
if (i == BCM2835_NUM_IRQS)
BUG();

chained_irq_enter(host_chip, desc);
Expand Down Expand Up @@ -1087,6 +1086,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct bcm2835_pinctrl *pc;
struct gpio_irq_chip *girq;
struct resource iomem;
int err, i;
const struct of_device_id *match;
Expand Down Expand Up @@ -1135,38 +1135,33 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
raw_spin_lock_init(&pc->irq_lock[i]);
}

girq = &pc->gpio_chip.irq;
girq->chip = &bcm2835_gpio_irq_chip;
girq->parent_handler = bcm2835_gpio_irq_handler;
girq->num_parents = BCM2835_NUM_IRQS;
girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
* irq handler then needs to figure out which group and
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
for (i = 0; i < BCM2835_NUM_IRQS; i++)
girq->parents[i] = irq_of_parse_and_map(np, i);
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;

err = gpiochip_add_data(&pc->gpio_chip, pc);
if (err) {
dev_err(dev, "could not add GPIO chip\n");
return err;
}

err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (err) {
dev_info(dev, "could not add irqchip\n");
return err;
}

for (i = 0; i < BCM2835_NUM_IRQS; i++) {
pc->irq[i] = irq_of_parse_and_map(np, i);

if (pc->irq[i] == 0)
continue;

/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
* irq handler then needs to figure out which group and
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
gpiochip_set_chained_irqchip(&pc->gpio_chip,
&bcm2835_gpio_irq_chip,
pc->irq[i],
bcm2835_gpio_irq_handler);
}

match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
if (match) {
bcm2835_pinctrl_desc.confops =
Expand Down

0 comments on commit 73345a1

Please sign in to comment.