diff options
author | Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | 2016-10-19 17:03:41 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-11-01 14:31:49 -0400 |
commit | 812d47889a8e418d7bea9bec383581a34c19183e (patch) | |
tree | 7be505e76bd8e2e929b91cce5ffa8a0d6f60b272 /drivers/gpio | |
parent | c7e9d39831a31682285cc31ddf7dd06c0fe59138 (diff) |
gpio/mvebu: Use irq_domain_add_linear
This fixes the irq allocation in this driver to not print:
irq: Cannot allocate irq_descs @ IRQ34, assuming pre-allocated
irq: Cannot allocate irq_descs @ IRQ66, assuming pre-allocated
Which happens because the driver already called irq_alloc_descs()
and so the change to use irq_domain_add_simple resulted in calling
irq_alloc_descs() twice.
Modernize the irq allocation in this driver to use the
irq_domain_add_linear flow directly and eliminate the use of
irq_domain_add_simple/legacy
Fixes: ce931f571b6d ("gpio/mvebu: convert to use irq_domain_add_simple()")
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-mvebu.c | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cd5dc27320a2..1ed6132b993c 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
@@ -293,10 +293,10 @@ static void mvebu_gpio_irq_ack(struct irq_data *d) | |||
293 | { | 293 | { |
294 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 294 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
295 | struct mvebu_gpio_chip *mvchip = gc->private; | 295 | struct mvebu_gpio_chip *mvchip = gc->private; |
296 | u32 mask = ~(1 << (d->irq - gc->irq_base)); | 296 | u32 mask = d->mask; |
297 | 297 | ||
298 | irq_gc_lock(gc); | 298 | irq_gc_lock(gc); |
299 | writel_relaxed(mask, mvebu_gpioreg_edge_cause(mvchip)); | 299 | writel_relaxed(~mask, mvebu_gpioreg_edge_cause(mvchip)); |
300 | irq_gc_unlock(gc); | 300 | irq_gc_unlock(gc); |
301 | } | 301 | } |
302 | 302 | ||
@@ -305,7 +305,7 @@ static void mvebu_gpio_edge_irq_mask(struct irq_data *d) | |||
305 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 305 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
306 | struct mvebu_gpio_chip *mvchip = gc->private; | 306 | struct mvebu_gpio_chip *mvchip = gc->private; |
307 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | 307 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
308 | u32 mask = 1 << (d->irq - gc->irq_base); | 308 | u32 mask = d->mask; |
309 | 309 | ||
310 | irq_gc_lock(gc); | 310 | irq_gc_lock(gc); |
311 | ct->mask_cache_priv &= ~mask; | 311 | ct->mask_cache_priv &= ~mask; |
@@ -319,8 +319,7 @@ static void mvebu_gpio_edge_irq_unmask(struct irq_data *d) | |||
319 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 319 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
320 | struct mvebu_gpio_chip *mvchip = gc->private; | 320 | struct mvebu_gpio_chip *mvchip = gc->private; |
321 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | 321 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
322 | 322 | u32 mask = d->mask; | |
323 | u32 mask = 1 << (d->irq - gc->irq_base); | ||
324 | 323 | ||
325 | irq_gc_lock(gc); | 324 | irq_gc_lock(gc); |
326 | ct->mask_cache_priv |= mask; | 325 | ct->mask_cache_priv |= mask; |
@@ -333,8 +332,7 @@ static void mvebu_gpio_level_irq_mask(struct irq_data *d) | |||
333 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 332 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
334 | struct mvebu_gpio_chip *mvchip = gc->private; | 333 | struct mvebu_gpio_chip *mvchip = gc->private; |
335 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | 334 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
336 | 335 | u32 mask = d->mask; | |
337 | u32 mask = 1 << (d->irq - gc->irq_base); | ||
338 | 336 | ||
339 | irq_gc_lock(gc); | 337 | irq_gc_lock(gc); |
340 | ct->mask_cache_priv &= ~mask; | 338 | ct->mask_cache_priv &= ~mask; |
@@ -347,8 +345,7 @@ static void mvebu_gpio_level_irq_unmask(struct irq_data *d) | |||
347 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 345 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
348 | struct mvebu_gpio_chip *mvchip = gc->private; | 346 | struct mvebu_gpio_chip *mvchip = gc->private; |
349 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | 347 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
350 | 348 | u32 mask = d->mask; | |
351 | u32 mask = 1 << (d->irq - gc->irq_base); | ||
352 | 349 | ||
353 | irq_gc_lock(gc); | 350 | irq_gc_lock(gc); |
354 | ct->mask_cache_priv |= mask; | 351 | ct->mask_cache_priv |= mask; |
@@ -462,7 +459,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) | |||
462 | for (i = 0; i < mvchip->chip.ngpio; i++) { | 459 | for (i = 0; i < mvchip->chip.ngpio; i++) { |
463 | int irq; | 460 | int irq; |
464 | 461 | ||
465 | irq = mvchip->irqbase + i; | 462 | irq = irq_find_mapping(mvchip->domain, i); |
466 | 463 | ||
467 | if (!(cause & (1 << i))) | 464 | if (!(cause & (1 << i))) |
468 | continue; | 465 | continue; |
@@ -655,6 +652,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) | |||
655 | struct irq_chip_type *ct; | 652 | struct irq_chip_type *ct; |
656 | struct clk *clk; | 653 | struct clk *clk; |
657 | unsigned int ngpios; | 654 | unsigned int ngpios; |
655 | bool have_irqs; | ||
658 | int soc_variant; | 656 | int soc_variant; |
659 | int i, cpu, id; | 657 | int i, cpu, id; |
660 | int err; | 658 | int err; |
@@ -665,6 +663,9 @@ static int mvebu_gpio_probe(struct platform_device *pdev) | |||
665 | else | 663 | else |
666 | soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION; | 664 | soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION; |
667 | 665 | ||
666 | /* Some gpio controllers do not provide irq support */ | ||
667 | have_irqs = of_irq_count(np) != 0; | ||
668 | |||
668 | mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), | 669 | mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), |
669 | GFP_KERNEL); | 670 | GFP_KERNEL); |
670 | if (!mvchip) | 671 | if (!mvchip) |
@@ -697,7 +698,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) | |||
697 | mvchip->chip.get = mvebu_gpio_get; | 698 | mvchip->chip.get = mvebu_gpio_get; |
698 | mvchip->chip.direction_output = mvebu_gpio_direction_output; | 699 | mvchip->chip.direction_output = mvebu_gpio_direction_output; |
699 | mvchip->chip.set = mvebu_gpio_set; | 700 | mvchip->chip.set = mvebu_gpio_set; |
700 | mvchip->chip.to_irq = mvebu_gpio_to_irq; | 701 | if (have_irqs) |
702 | mvchip->chip.to_irq = mvebu_gpio_to_irq; | ||
701 | mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK; | 703 | mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK; |
702 | mvchip->chip.ngpio = ngpios; | 704 | mvchip->chip.ngpio = ngpios; |
703 | mvchip->chip.can_sleep = false; | 705 | mvchip->chip.can_sleep = false; |
@@ -758,34 +760,30 @@ static int mvebu_gpio_probe(struct platform_device *pdev) | |||
758 | devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); | 760 | devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); |
759 | 761 | ||
760 | /* Some gpio controllers do not provide irq support */ | 762 | /* Some gpio controllers do not provide irq support */ |
761 | if (!of_irq_count(np)) | 763 | if (!have_irqs) |
762 | return 0; | 764 | return 0; |
763 | 765 | ||
764 | /* Setup the interrupt handlers. Each chip can have up to 4 | 766 | mvchip->domain = |
765 | * interrupt handlers, with each handler dealing with 8 GPIO | 767 | irq_domain_add_linear(np, ngpios, &irq_generic_chip_ops, NULL); |
766 | * pins. */ | 768 | if (!mvchip->domain) { |
767 | for (i = 0; i < 4; i++) { | 769 | dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", |
768 | int irq = platform_get_irq(pdev, i); | 770 | mvchip->chip.label); |
769 | 771 | return -ENODEV; | |
770 | if (irq < 0) | ||
771 | continue; | ||
772 | irq_set_chained_handler_and_data(irq, mvebu_gpio_irq_handler, | ||
773 | mvchip); | ||
774 | } | ||
775 | |||
776 | mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1); | ||
777 | if (mvchip->irqbase < 0) { | ||
778 | dev_err(&pdev->dev, "no irqs\n"); | ||
779 | return mvchip->irqbase; | ||
780 | } | 772 | } |
781 | 773 | ||
782 | gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase, | 774 | err = irq_alloc_domain_generic_chips( |
783 | mvchip->membase, handle_level_irq); | 775 | mvchip->domain, ngpios, 2, np->name, handle_level_irq, |
784 | if (!gc) { | 776 | IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_LEVEL, 0, 0); |
785 | dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); | 777 | if (err) { |
786 | return -ENOMEM; | 778 | dev_err(&pdev->dev, "couldn't allocate irq chips %s (DT).\n", |
779 | mvchip->chip.label); | ||
780 | goto err_domain; | ||
787 | } | 781 | } |
788 | 782 | ||
783 | /* NOTE: The common accessors cannot be used because of the percpu | ||
784 | * access to the mask registers | ||
785 | */ | ||
786 | gc = irq_get_domain_generic_chip(mvchip->domain, 0); | ||
789 | gc->private = mvchip; | 787 | gc->private = mvchip; |
790 | ct = &gc->chip_types[0]; | 788 | ct = &gc->chip_types[0]; |
791 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; | 789 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; |
@@ -803,27 +801,23 @@ static int mvebu_gpio_probe(struct platform_device *pdev) | |||
803 | ct->handler = handle_edge_irq; | 801 | ct->handler = handle_edge_irq; |
804 | ct->chip.name = mvchip->chip.label; | 802 | ct->chip.name = mvchip->chip.label; |
805 | 803 | ||
806 | irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, | 804 | /* Setup the interrupt handlers. Each chip can have up to 4 |
807 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 805 | * interrupt handlers, with each handler dealing with 8 GPIO |
806 | * pins. | ||
807 | */ | ||
808 | for (i = 0; i < 4; i++) { | ||
809 | int irq = platform_get_irq(pdev, i); | ||
808 | 810 | ||
809 | /* Setup irq domain on top of the generic chip. */ | 811 | if (irq < 0) |
810 | mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio, | 812 | continue; |
811 | mvchip->irqbase, | 813 | irq_set_chained_handler_and_data(irq, mvebu_gpio_irq_handler, |
812 | &irq_domain_simple_ops, | 814 | mvchip); |
813 | mvchip); | ||
814 | if (!mvchip->domain) { | ||
815 | dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", | ||
816 | mvchip->chip.label); | ||
817 | err = -ENODEV; | ||
818 | goto err_generic_chip; | ||
819 | } | 815 | } |
820 | 816 | ||
821 | return 0; | 817 | return 0; |
822 | 818 | ||
823 | err_generic_chip: | 819 | err_domain: |
824 | irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST, | 820 | irq_domain_remove(mvchip->domain); |
825 | IRQ_LEVEL | IRQ_NOPROBE); | ||
826 | kfree(gc); | ||
827 | 821 | ||
828 | return err; | 822 | return err; |
829 | } | 823 | } |