Commit 9517d76d authored by Haotian Zhang's avatar Haotian Zhang Committed by William Breathitt Gray
Browse files

counter: 104-quad-8: Fix incorrect return value in IRQ handler



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: 98ffe025 ("counter: 104-quad-8: Migrate to the regmap API")
Suggested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarHaotian 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: default avatarWilliam Breathitt Gray <wbg@kernel.org>
parent 23f94855
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -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,7 +1227,8 @@ 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",
			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;
}