Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756042AbcDNPhj (ORCPT ); Thu, 14 Apr 2016 11:37:39 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:56179 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755103AbcDNPhi (ORCPT ); Thu, 14 Apr 2016 11:37:38 -0400 Authentication-Results: ppops.net; spf=none smtp.mail=rf@opensource.wolfsonmicro.com From: Richard Fitzgerald To: CC: , Subject: [PATCH] mfd: arizona: Check if AOD interrupts are pending before dispatching Date: Thu, 14 Apr 2016 16:37:29 +0100 Message-ID: <1460648249-4979-1-git-send-email-rf@opensource.wolfsonmicro.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1603180000 definitions=main-1604140221 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1716 Lines: 55 Previously the arizona_irq_thread implementation would call handle_nested_irqs() to handle AOD interrupts without checking if any were actually pending. The kernel will see these as spurious IRQs and will eventually disable the IRQ. This patch ensures we only launch the nested handler if there are AOD interrupts pending in the codec. Signed-off-by: Simon Trimmer Signed-off-by: Richard Fitzgerald --- drivers/mfd/arizona-irq.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index edeb495..edaf592 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -97,7 +97,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) { struct arizona *arizona = data; bool poll; - unsigned int val; + unsigned int val, nest_irq; int ret; ret = pm_runtime_get_sync(arizona->dev); @@ -109,8 +109,23 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) do { poll = false; - if (arizona->aod_irq_chip) - handle_nested_irq(irq_find_mapping(arizona->virq, 0)); + if (arizona->aod_irq_chip) { + /* + * Check the AOD status register to determine whether + * the nested IRQ handler should be called. + */ + ret = regmap_read(arizona->regmap, + ARIZONA_AOD_IRQ1, + &val); + if (ret == 0 && val != 0) { + nest_irq = irq_find_mapping(arizona->virq, 0); + handle_nested_irq(nest_irq); + } else if (ret != 0) { + dev_err(arizona->dev, + "Failed to read AOD IRQ1 %d\n", + ret); + } + } /* * Check if one of the main interrupts is asserted and only -- 1.9.1