Skip to contentSkip to conversation

FAILED: patch "[PATCH] iio: adc: xilinx-xadc: free IRQ before cancelling the unmask" failed to apply to 5.15-stable tree

PATCH [email protected] 1 participant 1 message Oct 6

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 0f3f427076240e75ff265e61645627a71ca4918c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100633-subside-encroach-28c4@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 0f3f427076240e75ff265e61645627a71ca4918c Mon Sep 17 00:00:00 2001
From: Fan Wu <[email protected]>
Date: Mon, 3 Aug 2026 08:03:43 +0000
Subject: [PATCH] iio: adc: xilinx-xadc: free IRQ before cancelling the unmask
worker on unbind

The ZYNQ XADC alarm IRQ handler queues zynq_unmask_work via schedule_delayed_work(); that work is cleared by a devm callback. Register the devm callback before devm_request_irq() so the devres LIFO teardown frees the IRQ first, ensuring the handler can no longer queue work by the time the workqueue is cleared. Otherwise the handler could re-arm the work and run it after the xadc structure has been freed.

This issue was found by an in-house static analysis tool.

Fixes 2a9685d1a3b7 ("iio: adc: xilinx: use more devres helpers and remove remove()")
Assisted-by Codex:gpt-5.6
drivers/iio/adc/xilinx-xadc-core.c +5 -4
index cab66bb8cc1c..66202b3a3abb 100644
@@ -1401,13 +1401,14 @@ static int xadc_probe(struct platform_device *pdev)
 	}
 
 	if (irq > 0) {
-		ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler,
-				       0, dev_name(dev), indio_dev);
+		/* Clear out any work queued by the interrupt */
+		ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
+					       &xadc->zynq_unmask_work);
 		if (ret)
 			return ret;
 
-		ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
-					       &xadc->zynq_unmask_work);
+		ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler,
+				       0, dev_name(dev), indio_dev);
 		if (ret)
 			return ret;
 	}