If a irq is already disabled & masked, free_irq may cause a unbalanced irq shutdown/disable/mask, for example:
devm_request_irq->irq_startup->irq_enable disable_irq <-- disabled and masked devm_free_irq->irq_shutdown <-- try to disable it again This would confuse some pinctrl drivers which would control clk in irq_enable/irq_disable, for example pinctrl-rockchip/pinctrl-nomadik. This patch add a state check in irq_shutdown to prevent that. v2: Rewrite commit message. Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com> --- Changes in v2: Rewrite commit message. kernel/irq/chip.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 686be4b..816da03 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -206,14 +206,20 @@ int irq_startup(struct irq_desc *desc, bool resend) void irq_shutdown(struct irq_desc *desc) { - irq_state_set_disabled(desc); desc->depth = 1; + + if (unlikely(irqd_irq_disabled(&desc->irq_data) && + irqd_irq_masked(&desc->irq_data))) + goto out; + + irq_state_set_disabled(desc); if (desc->irq_data.chip->irq_shutdown) desc->irq_data.chip->irq_shutdown(&desc->irq_data); else if (desc->irq_data.chip->irq_disable) desc->irq_data.chip->irq_disable(&desc->irq_data); else desc->irq_data.chip->irq_mask(&desc->irq_data); +out: irq_domain_deactivate_irq(&desc->irq_data); irq_state_set_masked(desc); } -- 2.1.4