Messages in this thread Patch in this message | | | From | Jeffy Chen <> | Subject | [PATCH v3] genirq: Check irq disabled & masked states in irq_shutdown | Date | Sat, 27 May 2017 18:05:08 +0800 |
| |
If a irq is already disabled, irq_shutdown may try to disable it again, for example: devm_request_irq->irq_startup->irq_enable disable_irq <-- disabled devm_free_irq->irq_shutdown <-- disable it again
This would confuse some chips which require balanced irq enable and disable, for example pinctrl-rockchip & pinctrl-nomadik.
Add a state check before calling irq_disable to prevent that.
v2: Rewrite commit message. v3: Rewrite commit message and not skip irq_shutdown.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> ---
Changes in v3: Rewrite commit message and not skip irq_shutdown.
Changes in v2: Rewrite commit message.
kernel/irq/chip.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 686be4b..0ac0c56 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -206,13 +206,23 @@ int irq_startup(struct irq_desc *desc, bool resend) void irq_shutdown(struct irq_desc *desc) { + int irq_disabled = irqd_irq_disabled(&desc->irq_data); + irq_state_set_disabled(desc); desc->depth = 1; if (desc->irq_data.chip->irq_shutdown) desc->irq_data.chip->irq_shutdown(&desc->irq_data); - else if (desc->irq_data.chip->irq_disable) + /* + * 1/ Some chips may require balanced irq enable &_disable. + * 2/ Due to the lazy disable approach, a irq could be + * disabled but unmasked. + * + * So if this irq is already disabled, let's mask it instead + * of trying to call irq_disable again. + */ + else if (desc->irq_data.chip->irq_disable && !irq_disabled) desc->irq_data.chip->irq_disable(&desc->irq_data); - else + else if (desc->irq_data.chip->irq_mask) desc->irq_data.chip->irq_mask(&desc->irq_data); irq_domain_deactivate_irq(&desc->irq_data); irq_state_set_masked(desc); -- 2.1.4
| |