lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1460648249-4979-1-git-send-email-rf@opensource.wolfsonmicro.com>
Date:	Thu, 14 Apr 2016 16:37:29 +0100
From:	Richard Fitzgerald <rf@...nsource.wolfsonmicro.com>
To:	<lee.jones@...aro.org>
CC:	<patches@...nsource.wolfsonmicro.com>,
	<linux-kernel@...r.kernel.org>
Subject: [PATCH] mfd: arizona: Check if AOD interrupts are pending before dispatching

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 <simont@...nsource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@...nsource.wolfsonmicro.com>
---
 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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ