aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-08-19 13:07:14 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-08-22 12:37:51 -0400
commit6a33fa2b87513fee44cb8f0cd17b1acd6316bc6b (patch)
tree18dc3a7448a3db01cd41025bab34ce0317307c55
parent3ee0ce2a54dff07d09440723594df89bc1a12e79 (diff)
irqchip/mips-gic: Cleanup chip and handler setup
gic_shared_irq_domain_map() is called from gic_irq_domain_alloc() where the wrong chip has been set, and is then overwritten. Tidy this up by setting the correct chip the first time, and setting the handle_level_irq handler from gic_irq_domain_alloc() too. gic_shared_irq_domain_map() is also called from gic_irq_domain_map(), which now calls irq_set_chip_and_handler() to retain its previous behaviour. This patch prepares for a follow-on which will call gic_shared_irq_domain_map() from a callback where the lock on the struct irq_desc is held, which without this change would cause the call to irq_set_chip_and_handler() to lead to a deadlock. Fixes: c98c1822ee13 ("irqchip/mips-gic: Add device hierarchy domain") Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: Jason Cooper <jason@lakedaemon.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20160819170715.27820-1-paul.burton@imgtec.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/irqchip/irq-mips-gic.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index c5f33c3bd228..2e0f49992a98 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -713,9 +713,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
713 unsigned long flags; 713 unsigned long flags;
714 int i; 714 int i;
715 715
716 irq_set_chip_and_handler(virq, &gic_level_irq_controller,
717 handle_level_irq);
718
719 spin_lock_irqsave(&gic_lock, flags); 716 spin_lock_irqsave(&gic_lock, flags);
720 gic_map_to_pin(intr, gic_cpu_pin); 717 gic_map_to_pin(intr, gic_cpu_pin);
721 gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); 718 gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
@@ -732,6 +729,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
732{ 729{
733 if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) 730 if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS)
734 return gic_local_irq_domain_map(d, virq, hw); 731 return gic_local_irq_domain_map(d, virq, hw);
732
733 irq_set_chip_and_handler(virq, &gic_level_irq_controller,
734 handle_level_irq);
735
735 return gic_shared_irq_domain_map(d, virq, hw, 0); 736 return gic_shared_irq_domain_map(d, virq, hw, 0);
736} 737}
737 738
@@ -771,11 +772,13 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
771 hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i); 772 hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i);
772 773
773 ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq, 774 ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq,
774 &gic_edge_irq_controller, 775 &gic_level_irq_controller,
775 NULL); 776 NULL);
776 if (ret) 777 if (ret)
777 goto error; 778 goto error;
778 779
780 irq_set_handler(virq + i, handle_level_irq);
781
779 ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu); 782 ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu);
780 if (ret) 783 if (ret)
781 goto error; 784 goto error;