Skip to content

Commit 3351788

Browse files
Doug BergerMarc Zyngier
authored andcommitted
irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
Using the irq_gc_lock/irq_gc_unlock functions in the suspend and resume functions creates the opportunity for a deadlock during suspend, resume, and shutdown. Using the irq_gc_lock_irqsave/ irq_gc_unlock_irqrestore variants prevents this possible deadlock. Cc: stable@vger.kernel.org Fixes: 7f646e9 ("irqchip: brcmstb-l2: Add Broadcom Set Top Box Level-2 interrupt controller") Signed-off-by: Doug Berger <opendmb@gmail.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> [maz: tidied up $SUBJECT] Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent 539d378 commit 3351788

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

drivers/irqchip/irq-brcmstb-l2.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
129129
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
130130
struct irq_chip_type *ct = irq_data_get_chip_type(d);
131131
struct brcmstb_l2_intc_data *b = gc->private;
132+
unsigned long flags;
132133

133-
irq_gc_lock(gc);
134+
irq_gc_lock_irqsave(gc, flags);
134135
/* Save the current mask */
135136
b->saved_mask = irq_reg_readl(gc, ct->regs.mask);
136137

@@ -139,16 +140,17 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
139140
irq_reg_writel(gc, ~gc->wake_active, ct->regs.disable);
140141
irq_reg_writel(gc, gc->wake_active, ct->regs.enable);
141142
}
142-
irq_gc_unlock(gc);
143+
irq_gc_unlock_irqrestore(gc, flags);
143144
}
144145

145146
static void brcmstb_l2_intc_resume(struct irq_data *d)
146147
{
147148
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
148149
struct irq_chip_type *ct = irq_data_get_chip_type(d);
149150
struct brcmstb_l2_intc_data *b = gc->private;
151+
unsigned long flags;
150152

151-
irq_gc_lock(gc);
153+
irq_gc_lock_irqsave(gc, flags);
152154
if (ct->chip.irq_ack) {
153155
/* Clear unmasked non-wakeup interrupts */
154156
irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active,
@@ -158,7 +160,7 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
158160
/* Restore the saved mask */
159161
irq_reg_writel(gc, b->saved_mask, ct->regs.disable);
160162
irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable);
161-
irq_gc_unlock(gc);
163+
irq_gc_unlock_irqrestore(gc, flags);
162164
}
163165

164166
static int __init brcmstb_l2_intc_of_init(struct device_node *np,

0 commit comments

Comments
 (0)