aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Berger <opendmb@gmail.com>2017-10-24 15:54:50 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-10-31 05:34:40 -0400
commit0ba31dc201deb4f47277d7ff676b45da31c530e4 (patch)
treebba6d82d871dabab3374764818c6bec6eb89cdd5
parent633007a36e51c5dd85a20e9ebd17de12566cf2c2 (diff)
gpio: brcmstb: consolidate interrupt domains
The GPIOLIB IRQ chip helpers were very appealing, but badly broke the 1:1 mapping between a GPIO controller's device_node and its interrupt domain. When another device-tree node references a GPIO device as its interrupt parent, the irq_create_of_mapping() function looks for the irq domain of the GPIO device and since all bank irq domains reference the same GPIO device node it always resolves to the irq domain of the first bank regardless of which bank the number of the GPIO should resolve. This domain can only map hwirq numbers 0-31 so interrupts on GPIO above that can't be mapped by the device-tree. This commit effectively reverts the patch from Gregory Fong [1] that was accepted upstream and replaces it with a consolidated irq domain implementation with one larger interrupt domain per GPIO controller instance spanning multiple GPIO banks based on an earlier patch [2] also submitted by Gregory Fong. [1] https://patchwork.kernel.org/patch/6921561/ [2] https://patchwork.kernel.org/patch/6347811/ Fixes: 19a7b6940b78 ("gpio: brcmstb: Add interrupt and wakeup source support") Signed-off-by: Doug Berger <opendmb@gmail.com> Reviewed-by: Gregory Fong <gregory.0xf0@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/gpio-brcmstb.c188
2 files changed, 146 insertions, 44 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e7f3f39e69df..f002edda555b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -139,7 +139,7 @@ config GPIO_BRCMSTB
139 default y if (ARCH_BRCMSTB || BMIPS_GENERIC) 139 default y if (ARCH_BRCMSTB || BMIPS_GENERIC)
140 depends on OF_GPIO && (ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST) 140 depends on OF_GPIO && (ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST)
141 select GPIO_GENERIC 141 select GPIO_GENERIC
142 select GPIOLIB_IRQCHIP 142 select IRQ_DOMAIN
143 help 143 help
144 Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs. 144 Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
145 145
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 183863902f7f..9a8c603625a3 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -38,20 +38,22 @@ struct brcmstb_gpio_bank {
38 struct gpio_chip gc; 38 struct gpio_chip gc;
39 struct brcmstb_gpio_priv *parent_priv; 39 struct brcmstb_gpio_priv *parent_priv;
40 u32 width; 40 u32 width;
41 struct irq_chip irq_chip;
42}; 41};
43 42
44struct brcmstb_gpio_priv { 43struct brcmstb_gpio_priv {
45 struct list_head bank_list; 44 struct list_head bank_list;
46 void __iomem *reg_base; 45 void __iomem *reg_base;
47 struct platform_device *pdev; 46 struct platform_device *pdev;
47 struct irq_domain *irq_domain;
48 struct irq_chip irq_chip;
48 int parent_irq; 49 int parent_irq;
49 int gpio_base; 50 int gpio_base;
51 int num_gpios;
50 int parent_wake_irq; 52 int parent_wake_irq;
51 struct notifier_block reboot_notifier; 53 struct notifier_block reboot_notifier;
52}; 54};
53 55
54#define MAX_GPIO_PER_BANK 32 56#define MAX_GPIO_PER_BANK 32
55#define GPIO_BANK(gpio) ((gpio) >> 5) 57#define GPIO_BANK(gpio) ((gpio) >> 5)
56/* assumes MAX_GPIO_PER_BANK is a multiple of 2 */ 58/* assumes MAX_GPIO_PER_BANK is a multiple of 2 */
57#define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1)) 59#define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1))
@@ -78,24 +80,42 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
78 return status; 80 return status;
79} 81}
80 82
83static int brcmstb_gpio_hwirq_to_offset(irq_hw_number_t hwirq,
84 struct brcmstb_gpio_bank *bank)
85{
86 return hwirq - (bank->gc.base - bank->parent_priv->gpio_base);
87}
88
81static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank, 89static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
82 unsigned int offset, bool enable) 90 unsigned int hwirq, bool enable)
83{ 91{
84 struct gpio_chip *gc = &bank->gc; 92 struct gpio_chip *gc = &bank->gc;
85 struct brcmstb_gpio_priv *priv = bank->parent_priv; 93 struct brcmstb_gpio_priv *priv = bank->parent_priv;
94 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(hwirq, bank));
86 u32 imask; 95 u32 imask;
87 unsigned long flags; 96 unsigned long flags;
88 97
89 spin_lock_irqsave(&gc->bgpio_lock, flags); 98 spin_lock_irqsave(&gc->bgpio_lock, flags);
90 imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id)); 99 imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id));
91 if (enable) 100 if (enable)
92 imask |= BIT(offset); 101 imask |= mask;
93 else 102 else
94 imask &= ~BIT(offset); 103 imask &= ~mask;
95 gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask); 104 gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
96 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 105 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
97} 106}
98 107
108static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
109{
110 struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
111 /* gc_offset is relative to this gpio_chip; want real offset */
112 int hwirq = offset + (gc->base - priv->gpio_base);
113
114 if (hwirq >= priv->num_gpios)
115 return -ENXIO;
116 return irq_create_mapping(priv->irq_domain, hwirq);
117}
118
99/* -------------------- IRQ chip functions -------------------- */ 119/* -------------------- IRQ chip functions -------------------- */
100 120
101static void brcmstb_gpio_irq_mask(struct irq_data *d) 121static void brcmstb_gpio_irq_mask(struct irq_data *d)
@@ -119,7 +139,7 @@ static void brcmstb_gpio_irq_ack(struct irq_data *d)
119 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 139 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
120 struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); 140 struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc);
121 struct brcmstb_gpio_priv *priv = bank->parent_priv; 141 struct brcmstb_gpio_priv *priv = bank->parent_priv;
122 u32 mask = BIT(d->hwirq); 142 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank));
123 143
124 gc->write_reg(priv->reg_base + GIO_STAT(bank->id), mask); 144 gc->write_reg(priv->reg_base + GIO_STAT(bank->id), mask);
125} 145}
@@ -129,7 +149,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
129 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 149 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
130 struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); 150 struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc);
131 struct brcmstb_gpio_priv *priv = bank->parent_priv; 151 struct brcmstb_gpio_priv *priv = bank->parent_priv;
132 u32 mask = BIT(d->hwirq); 152 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank));
133 u32 edge_insensitive, iedge_insensitive; 153 u32 edge_insensitive, iedge_insensitive;
134 u32 edge_config, iedge_config; 154 u32 edge_config, iedge_config;
135 u32 level, ilevel; 155 u32 level, ilevel;
@@ -226,18 +246,20 @@ static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data)
226static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank) 246static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank)
227{ 247{
228 struct brcmstb_gpio_priv *priv = bank->parent_priv; 248 struct brcmstb_gpio_priv *priv = bank->parent_priv;
229 struct irq_domain *irq_domain = bank->gc.irqdomain; 249 struct irq_domain *domain = priv->irq_domain;
250 int hwbase = bank->gc.base - priv->gpio_base;
230 unsigned long status; 251 unsigned long status;
231 252
232 while ((status = brcmstb_gpio_get_active_irqs(bank))) { 253 while ((status = brcmstb_gpio_get_active_irqs(bank))) {
233 int bit; 254 unsigned int irq, offset;
234 255
235 for_each_set_bit(bit, &status, 32) { 256 for_each_set_bit(offset, &status, 32) {
236 if (bit >= bank->width) 257 if (offset >= bank->width)
237 dev_warn(&priv->pdev->dev, 258 dev_warn(&priv->pdev->dev,
238 "IRQ for invalid GPIO (bank=%d, offset=%d)\n", 259 "IRQ for invalid GPIO (bank=%d, offset=%d)\n",
239 bank->id, bit); 260 bank->id, offset);
240 generic_handle_irq(irq_find_mapping(irq_domain, bit)); 261 irq = irq_linear_revmap(domain, hwbase + offset);
262 generic_handle_irq(irq);
241 } 263 }
242 } 264 }
243} 265}
@@ -245,8 +267,7 @@ static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank)
245/* Each UPG GIO block has one IRQ for all banks */ 267/* Each UPG GIO block has one IRQ for all banks */
246static void brcmstb_gpio_irq_handler(struct irq_desc *desc) 268static void brcmstb_gpio_irq_handler(struct irq_desc *desc)
247{ 269{
248 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 270 struct brcmstb_gpio_priv *priv = irq_desc_get_handler_data(desc);
249 struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
250 struct irq_chip *chip = irq_desc_get_chip(desc); 271 struct irq_chip *chip = irq_desc_get_chip(desc);
251 struct brcmstb_gpio_bank *bank; 272 struct brcmstb_gpio_bank *bank;
252 273
@@ -272,6 +293,63 @@ static int brcmstb_gpio_reboot(struct notifier_block *nb,
272 return NOTIFY_DONE; 293 return NOTIFY_DONE;
273} 294}
274 295
296static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank(
297 struct brcmstb_gpio_priv *priv, irq_hw_number_t hwirq)
298{
299 struct brcmstb_gpio_bank *bank;
300 int i = 0;
301
302 /* banks are in descending order */
303 list_for_each_entry_reverse(bank, &priv->bank_list, node) {
304 i += bank->gc.ngpio;
305 if (hwirq < i)
306 return bank;
307 }
308 return NULL;
309}
310
311/*
312 * This lock class tells lockdep that GPIO irqs are in a different
313 * category than their parents, so it won't report false recursion.
314 */
315static struct lock_class_key brcmstb_gpio_irq_lock_class;
316
317
318static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq,
319 irq_hw_number_t hwirq)
320{
321 struct brcmstb_gpio_priv *priv = d->host_data;
322 struct brcmstb_gpio_bank *bank =
323 brcmstb_gpio_hwirq_to_bank(priv, hwirq);
324 struct platform_device *pdev = priv->pdev;
325 int ret;
326
327 if (!bank)
328 return -EINVAL;
329
330 dev_dbg(&pdev->dev, "Mapping irq %d for gpio line %d (bank %d)\n",
331 irq, (int)hwirq, bank->id);
332 ret = irq_set_chip_data(irq, &bank->gc);
333 if (ret < 0)
334 return ret;
335 irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class);
336 irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq);
337 irq_set_noprobe(irq);
338 return 0;
339}
340
341static void brcmstb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq)
342{
343 irq_set_chip_and_handler(irq, NULL, NULL);
344 irq_set_chip_data(irq, NULL);
345}
346
347static const struct irq_domain_ops brcmstb_gpio_irq_domain_ops = {
348 .map = brcmstb_gpio_irq_map,
349 .unmap = brcmstb_gpio_irq_unmap,
350 .xlate = irq_domain_xlate_twocell,
351};
352
275/* Make sure that the number of banks matches up between properties */ 353/* Make sure that the number of banks matches up between properties */
276static int brcmstb_gpio_sanity_check_banks(struct device *dev, 354static int brcmstb_gpio_sanity_check_banks(struct device *dev,
277 struct device_node *np, struct resource *res) 355 struct device_node *np, struct resource *res)
@@ -293,13 +371,25 @@ static int brcmstb_gpio_remove(struct platform_device *pdev)
293{ 371{
294 struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev); 372 struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev);
295 struct brcmstb_gpio_bank *bank; 373 struct brcmstb_gpio_bank *bank;
296 int ret = 0; 374 int offset, ret = 0, virq;
297 375
298 if (!priv) { 376 if (!priv) {
299 dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); 377 dev_err(&pdev->dev, "called %s without drvdata!\n", __func__);
300 return -EFAULT; 378 return -EFAULT;
301 } 379 }
302 380
381 if (priv->parent_irq > 0)
382 irq_set_chained_handler_and_data(priv->parent_irq, NULL, NULL);
383
384 /* Remove all IRQ mappings and delete the domain */
385 if (priv->irq_domain) {
386 for (offset = 0; offset < priv->num_gpios; offset++) {
387 virq = irq_find_mapping(priv->irq_domain, offset);
388 irq_dispose_mapping(virq);
389 }
390 irq_domain_remove(priv->irq_domain);
391 }
392
303 /* 393 /*
304 * You can lose return values below, but we report all errors, and it's 394 * You can lose return values below, but we report all errors, and it's
305 * more important to actually perform all of the steps. 395 * more important to actually perform all of the steps.
@@ -347,26 +437,24 @@ static int brcmstb_gpio_of_xlate(struct gpio_chip *gc,
347 return offset; 437 return offset;
348} 438}
349 439
350/* Before calling, must have bank->parent_irq set and gpiochip registered */ 440/* priv->parent_irq and priv->num_gpios must be set before calling */
351static int brcmstb_gpio_irq_setup(struct platform_device *pdev, 441static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
352 struct brcmstb_gpio_bank *bank) 442 struct brcmstb_gpio_priv *priv)
353{ 443{
354 struct brcmstb_gpio_priv *priv = bank->parent_priv;
355 struct device *dev = &pdev->dev; 444 struct device *dev = &pdev->dev;
356 struct device_node *np = dev->of_node; 445 struct device_node *np = dev->of_node;
357 int err; 446 int err;
358 447
359 bank->irq_chip.name = dev_name(dev); 448 priv->irq_domain =
360 bank->irq_chip.irq_mask = brcmstb_gpio_irq_mask; 449 irq_domain_add_linear(np, priv->num_gpios,
361 bank->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask; 450 &brcmstb_gpio_irq_domain_ops,
362 bank->irq_chip.irq_ack = brcmstb_gpio_irq_ack; 451 priv);
363 bank->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type; 452 if (!priv->irq_domain) {
364 453 dev_err(dev, "Couldn't allocate IRQ domain\n");
365 /* Ensures that all non-wakeup IRQs are disabled at suspend */ 454 return -ENXIO;
366 bank->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND; 455 }
367 456
368 if (IS_ENABLED(CONFIG_PM_SLEEP) && !priv->parent_wake_irq && 457 if (of_property_read_bool(np, "wakeup-source")) {
369 of_property_read_bool(np, "wakeup-source")) {
370 priv->parent_wake_irq = platform_get_irq(pdev, 1); 458 priv->parent_wake_irq = platform_get_irq(pdev, 1);
371 if (priv->parent_wake_irq < 0) { 459 if (priv->parent_wake_irq < 0) {
372 priv->parent_wake_irq = 0; 460 priv->parent_wake_irq = 0;
@@ -387,7 +475,7 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
387 475
388 if (err < 0) { 476 if (err < 0) {
389 dev_err(dev, "Couldn't request wake IRQ"); 477 dev_err(dev, "Couldn't request wake IRQ");
390 return err; 478 goto out_free_domain;
391 } 479 }
392 480
393 priv->reboot_notifier.notifier_call = 481 priv->reboot_notifier.notifier_call =
@@ -396,17 +484,28 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
396 } 484 }
397 } 485 }
398 486
487 priv->irq_chip.name = dev_name(dev);
488 priv->irq_chip.irq_disable = brcmstb_gpio_irq_mask;
489 priv->irq_chip.irq_mask = brcmstb_gpio_irq_mask;
490 priv->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask;
491 priv->irq_chip.irq_ack = brcmstb_gpio_irq_ack;
492 priv->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type;
493
494 /* Ensures that all non-wakeup IRQs are disabled at suspend */
495 priv->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
496
399 if (priv->parent_wake_irq) 497 if (priv->parent_wake_irq)
400 bank->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake; 498 priv->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake;
401 499
402 err = gpiochip_irqchip_add(&bank->gc, &bank->irq_chip, 0, 500 irq_set_chained_handler_and_data(priv->parent_irq,
403 handle_level_irq, IRQ_TYPE_NONE); 501 brcmstb_gpio_irq_handler, priv);
404 if (err)
405 return err;
406 gpiochip_set_chained_irqchip(&bank->gc, &bank->irq_chip,
407 priv->parent_irq, brcmstb_gpio_irq_handler);
408 502
409 return 0; 503 return 0;
504
505out_free_domain:
506 irq_domain_remove(priv->irq_domain);
507
508 return err;
410} 509}
411 510
412static int brcmstb_gpio_probe(struct platform_device *pdev) 511static int brcmstb_gpio_probe(struct platform_device *pdev)
@@ -511,6 +610,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
511 gc->of_xlate = brcmstb_gpio_of_xlate; 610 gc->of_xlate = brcmstb_gpio_of_xlate;
512 /* not all ngpio lines are valid, will use bank width later */ 611 /* not all ngpio lines are valid, will use bank width later */
513 gc->ngpio = MAX_GPIO_PER_BANK; 612 gc->ngpio = MAX_GPIO_PER_BANK;
613 if (priv->parent_irq > 0)
614 gc->to_irq = brcmstb_gpio_to_irq;
514 615
515 /* 616 /*
516 * Mask all interrupts by default, since wakeup interrupts may 617 * Mask all interrupts by default, since wakeup interrupts may
@@ -526,12 +627,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
526 } 627 }
527 gpio_base += gc->ngpio; 628 gpio_base += gc->ngpio;
528 629
529 if (priv->parent_irq > 0) {
530 err = brcmstb_gpio_irq_setup(pdev, bank);
531 if (err)
532 goto fail;
533 }
534
535 dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id, 630 dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id,
536 gc->base, gc->ngpio, bank->width); 631 gc->base, gc->ngpio, bank->width);
537 632
@@ -541,6 +636,13 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
541 num_banks++; 636 num_banks++;
542 } 637 }
543 638
639 priv->num_gpios = gpio_base - priv->gpio_base;
640 if (priv->parent_irq > 0) {
641 err = brcmstb_gpio_irq_setup(pdev, priv);
642 if (err)
643 goto fail;
644 }
645
544 dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", 646 dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n",
545 num_banks, priv->gpio_base, gpio_base - 1); 647 num_banks, priv->gpio_base, gpio_base - 1);
546 648