]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
counter: 104-quad-8: Fix incorrect return value in IRQ handler
authorHaotian Zhang <vulab@iscas.ac.cn>
Mon, 15 Dec 2025 02:01:14 +0000 (10:01 +0800)
committerWilliam Breathitt Gray <wbg@kernel.org>
Mon, 22 Dec 2025 11:03:23 +0000 (20:03 +0900)
quad8_irq_handler() should return irqreturn_t enum values, but it
directly returns negative errno codes from regmap operations on error.

Return IRQ_NONE if the interrupt status cannot be read. If clearing the
interrupt fails, return IRQ_HANDLED to prevent the kernel from disabling
the IRQ line due to a spurious interrupt storm. Also, log these regmap
failures with dev_WARN_ONCE.

Fixes: 98ffe0252911 ("counter: 104-quad-8: Migrate to the regmap API")
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
Link: https://lore.kernel.org/r/20251215020114.1913-1-vulab@iscas.ac.cn
Cc: stable@vger.kernel.org
Signed-off-by: William Breathitt Gray <wbg@kernel.org>
drivers/counter/104-quad-8.c

index ce81fc4e1ae76319e1a20327135a7419bdb91ae1..573b2fe93253e514836bdcbf8bd8ccff318f0924 100644 (file)
@@ -1192,6 +1192,7 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
 {
        struct counter_device *counter = private;
        struct quad8 *const priv = counter_priv(counter);
+       struct device *dev = counter->parent;
        unsigned int status;
        unsigned long irq_status;
        unsigned long channel;
@@ -1200,8 +1201,11 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
        int ret;
 
        ret = regmap_read(priv->map, QUAD8_INTERRUPT_STATUS, &status);
-       if (ret)
-               return ret;
+       if (ret) {
+               dev_WARN_ONCE(dev, true,
+                       "Attempt to read Interrupt Status Register failed: %d\n", ret);
+               return IRQ_NONE;
+       }
        if (!status)
                return IRQ_NONE;
 
@@ -1223,8 +1227,9 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
                                break;
                default:
                        /* should never reach this path */
-                       WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
-                                 flg_pins, channel);
+                       dev_WARN_ONCE(dev, true,
+                               "invalid interrupt trigger function %u configured for channel %lu\n",
+                               flg_pins, channel);
                        continue;
                }
 
@@ -1232,8 +1237,11 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
        }
 
        ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION, CLEAR_PENDING_INTERRUPTS);
-       if (ret)
-               return ret;
+       if (ret) {
+               dev_WARN_ONCE(dev, true,
+                       "Attempt to clear pending interrupts by writing to Channel Operation Register failed: %d\n", ret);
+               return IRQ_HANDLED;
+       }
 
        return IRQ_HANDLED;
 }