From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752003AbdE0Ew5 (ORCPT ); Sat, 27 May 2017 00:52:57 -0400 Received: from regular1.263xmail.com ([211.150.99.130]:45705 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751971AbdE0Ewz (ORCPT ); Sat, 27 May 2017 00:52:55 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-RL-SENDER: jeffy.chen@rock-chips.com X-FST-TO: linux-kernel@vger.kernel.org X-SENDER-IP: 103.29.142.67 X-LOGIN-NAME: jeffy.chen@rock-chips.com X-UNIQUE-TAG: <62c6ba57a0a923e6b98d2cd449380f0b> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 From: Jeffy Chen To: linux-kernel@vger.kernel.org, tglx@linutronix.de Cc: briannorris@chromium.org, dianders@chromium.org, tfiga@chromium.org, Jeffy Chen Subject: [PATCH v2] genirq: Check irq disabled & masked states in irq_shutdown Date: Sat, 27 May 2017 12:52:45 +0800 Message-Id: <1495860765-32399-1-git-send-email-jeffy.chen@rock-chips.com> X-Mailer: git-send-email 2.1.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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