Patch "pinctrl: mcp23s08: fix race condition in irq handler" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    pinctrl: mcp23s08: fix race condition in irq handler

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-mcp23s08-fix-race-condition-in-irq-handler.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 5d13b7016060d6e0d2b8d71a0aa950fc2cc9cd78
Author: Radim Pavlik <radim.pavlik@xxxxxxxxxxxxxxxxxx>
Date:   Tue Jun 1 10:48:18 2021 +0000

    pinctrl: mcp23s08: fix race condition in irq handler
    
    [ Upstream commit 897120d41e7afd9da435cb00041a142aeeb53c07 ]
    
    Checking value of MCP_INTF in mcp23s08_irq suggests that the handler may be
    called even when there is no interrupt pending.
    
    But the actual interrupt could happened between reading MCP_INTF and MCP_GPIO.
    In this situation we got nothing from MCP_INTF, but the event gets acknowledged
    on the expander by reading MCP_GPIO. This leads to losing events.
    
    Fix the problem by not reading any register until we see something in MCP_INTF.
    
    The error was reproduced and fix tested on MCP23017.
    
    Signed-off-by: Radim Pavlik <radim.pavlik@xxxxxxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/AM7PR06MB6769E1183F68DEBB252F665ABA3E9@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
index d8bcbefcba89..9d5e2d9b6b93 100644
--- a/drivers/pinctrl/pinctrl-mcp23s08.c
+++ b/drivers/pinctrl/pinctrl-mcp23s08.c
@@ -459,6 +459,11 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
 	if (mcp_read(mcp, MCP_INTF, &intf))
 		goto unlock;
 
+	if (intf == 0) {
+		/* There is no interrupt pending */
+		return IRQ_HANDLED;
+	}
+
 	if (mcp_read(mcp, MCP_INTCAP, &intcap))
 		goto unlock;
 
@@ -476,11 +481,6 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
 	mcp->cached_gpio = gpio;
 	mutex_unlock(&mcp->lock);
 
-	if (intf == 0) {
-		/* There is no interrupt pending */
-		return IRQ_HANDLED;
-	}
-
 	dev_dbg(mcp->chip.parent,
 		"intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n",
 		intcap, intf, gpio_orig, gpio);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux