watchdog: qcom: Propagate errors from optional IRQ lookup
Subsystems (4)
PATCH 1/4 watchdog: qcom: Propagate errors from optional IRQ lookup
From: bui duc phuc <[email protected]>
platform_get_irq_optional() returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ, -ENXIO indicates that no IRQ is available, while other errors should be propagated.
Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by platform_get_irq_optional() other than -ENXIO, so that failures are properly reported to the caller.
--- drivers/watchdog/qcom-wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/watchdog/qcom-wdt.c +2 -2
@@ -298,8 +298,8 @@ static int qcom_wdt_probe(struct platform_device *pdev) wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout =1 ; }else { -if (irq == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (irq != -ENXIO ) +return irq; wdt->wdd.info = &qcom_wdt_info; }
Signature · 1 line
2.43.0
PATCH 2/4 watchdog: mediatek: Propagate errors from optional IRQ lookup
From: bui duc phuc <[email protected]>
platform_get_irq_optional() returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ, -ENXIO indicates that no IRQ is available, while other errors should be propagated.
Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by platform_get_irq_optional() other than -ENXIO, so that failures are properly reported to the caller.
--- drivers/watchdog/mtk_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/watchdog/mtk_wdt.c +2 -2
@@ -422,8 +422,8 @@ static int mtk_wdt_probe(struct platform_device *pdev) mtk_wdt->wdt_dev.info = &mtk_wdt_pt_info; mtk_wdt->wdt_dev.pretimeout =WDT_MAX_TIMEOUT /2 ; }else { -if (irq == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (irq != -ENXIO ) +return irq; mtk_wdt->wdt_dev.info = &mtk_wdt_info; }
Signature · 1 line
2.43.0
Re: [PATCH 2/4] watchdog: mediatek: Propagate errors from optional IRQ lookup
Quoted 11 lines · On Fri, Aug 07, 2026 at 03:16:50PM +0700, [email protected] wrote:
From: bui duc phuc <[email protected]>
platform_get_irq_optional()returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ,-ENXIOindicates that no IRQ is available, while other errors should be propagated.Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by
platform_get_irq_optional()other than-ENXIO, so that failures are properly reported to the caller.Signed-off-by bui duc phuc <[email protected]>
Applied.
Thanks,
Guenter
PATCH 3/4 watchdog: dw_wdt: Propagate errors from optional IRQ lookup
In reply to [email protected]From: bui duc phuc <[email protected]>
platform_get_irq_optional() returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ, -ENXIO indicates that no IRQ is available, while other errors should be propagated.
Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by platform_get_irq_optional() other than -ENXIO, so that failures are properly reported to the caller.
--- drivers/watchdog/dw_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/dw_wdt.c +1 -1
@@ -611,7 +611,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) dw_wdt->wdd.info = &dw_wdt_pt_ident; }else { -if (ret == -EPROBE_DEFER ) +if (ret != -ENXIO )return ret; dw_wdt->wdd.info = &dw_wdt_ident;
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH 3/4] watchdog: dw_wdt: Propagate errors from optional IRQ lookup
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Hardware register access and shared IRQ registration occur before device is taken out of reset, which can cause an external abort or bus stall. This problem wasn't introduced by this patch, but it is a critical hardware lifecycle violation. --
--- Patch [3]: [PATCH 3/4] watchdog: dw_wdt: Propagate errors from optional IRQ lookup --- commit 415108e73d198e9211e81c51098b9fd10a005104
Author: bui duc phuc <[email protected]>
watchdog: dw_wdt: Propagate errors from optional IRQ lookup
This commit modifies dw_wdt_drv_probe() to propagate all error codes returned by platform_get_irq_optional() other than -ENXIO. This ensures failures are properly reported to the caller instead of only checking for -EPROBE_DEFER.
drivers/watchdog/dw_wdt.c static int dw_wdt_drv_probe(struct platform_device *pdev) · line 617
Quoted 13 lines
drivers/watchdog/dw_wdt.c +1
-1@@ -611,7 +611,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) dw_wdt->wdd.info = &dw_wdt_pt_ident; }else { -if (ret == -EPROBE_DEFER ) +if (ret != -ENXIO )return ret; dw_wdt->wdd.info = &dw_wdt_ident;
[Severity: High]
This is a pre-existing issue, but does this function perform register accesses and register a shared interrupt before the device is taken out of reset?
Looking at the sequence of operations in dw_wdt_drv_probe():
dw_wdt_drv_probe() {
...
/* Enable normal reset without pre-timeout by default. */
dw_wdt_update_mode(dw_wdt, DW_WDT_RMOD_RESET);
...
ret = devm_request_irq(dev, ret, dw_wdt_irq, IRQF_SHARED ...);
...
reset_control_deassert(dw_wdt->rst);
...
}If the hardware starts in a reset state, could the register I/O inside dw_wdt_update_mode() trigger a synchronous external abort or system hang because it occurs before reset_control_deassert() is called?
Additionally, since devm_request_irq() is called with IRQF_SHARED before the reset is deasserted, if another device on the same IRQ line triggers an interrupt, would dw_wdt_irq() execute and attempt to read the watchdog interrupt status register while the device is still held in reset?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
Re: [PATCH 3/4] watchdog: dw_wdt: Propagate errors from optional IRQ lookup
In reply to [email protected]Quoted 11 lines · On Fri, Aug 07, 2026 at 03:16:51PM +0700, [email protected] wrote:
From: bui duc phuc <[email protected]>
platform_get_irq_optional()returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ,-ENXIOindicates that no IRQ is available, while other errors should be propagated.Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by
platform_get_irq_optional()other than-ENXIO, so that failures are properly reported to the caller.Signed-off-by bui duc phuc <[email protected]>
Applied.
Thanks,
Guenter
PATCH 4/4 watchdog: aspeed: Propagate errors from optional IRQ lookup
In reply to [email protected]From: bui duc phuc <[email protected]>
platform_get_irq_optional() returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ, -ENXIO indicates that no IRQ is available, while other errors should be propagated.
Propagate errors such as -EPROBE_DEFER and -EINVAL instead of continuing probe without the IRQ.
--- drivers/watchdog/aspeed_wdt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/watchdog/aspeed_wdt.c +2 -0
@@ -429,6 +429,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev)if (wdt->cfg->irq_mask) {int irq =platform_get_irq_optional (pdev,0 ); +if (irq <0 && irq != -ENXIO ) +return irq;if (irq >0 ) { ret = devm_request_irq(dev, irq, aspeed_wdt_irq, IRQF_SHARED, dev_name(dev),
Signature · 1 line
2.43.0
Guenter Roeck
maintainerRe: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
Quoted 19 lines · On Fri, Aug 07, 2026 at 03:16:52PM +0700, [email protected] wrote:
From: bui duc phuc <[email protected]>
platform_get_irq_optional()returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ,-ENXIOindicates that no IRQ is available, while other errors should be propagated.Propagate errors such as -EPROBE_DEFER and
-EINVALinstead of continuing probe without the IRQ.Signed-off-by bui duc phuc <[email protected]>--- drivers/watchdog/aspeed_wdt.c | 2 ++ 1 file changed, 2 insertions(+)drivers/watchdog/aspeed_wdt.c +0
-0
drivers/watchdog/aspeed_wdt.c static int aspeed_wdt_probe(struct platform_device *pdev) · line 434
Quoted 6 lines
drivers/watchdog/aspeed_wdt.c +2
-0@@ -429,6 +429,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev)if (wdt->cfg->irq_mask) {int irq =platform_get_irq_optional (pdev,0 ); +if (irq <0 && irq != -ENXIO ) +return irq;if (irq >0 ) {
This if () is no longer needed.
Thanks,
Guenter
Quoted 2 lines
drivers/watchdog/aspeed_wdt.c +0
-0ret = devm_request_irq(dev, irq, aspeed_wdt_irq, IRQF_SHARED, dev_name(dev),
Re: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
Hi Guenter,
Thank you for your review.
Quoted 6 lines
drivers/watchdog/aspeed_wdt.c static int aspeed_wdt_probe(struct platform_device *pdev) · line 434
Quoted 3 lines
drivers/watchdog/aspeed_wdt.c +2
-0+if (irq <0 && irq != -ENXIO ) +return irq;if (irq >0 ) {This if () is no longer needed.
If we remove the if (irq > 0) check, irq can be -ENXIO and would be passed to devm_request_irq().
I see that the irq argument of devm_request_irq() is an unsigned int. Would it be safe to pass -ENXIO to it in this case?
Best regards,
Phuc
Guenter Roeck
maintainerRe: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
Quoted 8 lines · Bui Duc Phuc
Hi Guenter,
Thank you for your review.
Quoted 4 lines
Quoted 3 lines
drivers/watchdog/aspeed_wdt.c +2
-0+if (irq <0 && irq != -ENXIO ) +return irq;if (irq >0 ) {
Quoted 8 lines
Quoted 2 lines
This if () is no longer needed.
If we remove the if (irq > 0) check, irq can be
-ENXIOand would be passed todevm_request_irq().
I see that the irq argument ofdevm_request_irq()is an unsigned int. Would it be safe to pass-ENXIOto it in this case?
No, sorry, I was wrong.
Guenter
Re: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
Hi Guenter,
Thank you for your feedback.
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
+ return irq; if (irq > 0) {This if () is no longer needed.
Quoted 7 lines
Quoted 5 lines
If we remove the if (irq > 0) check, irq can be
-ENXIOand would be passed todevm_request_irq().
I see that the irq argument ofdevm_request_irq()is an unsigned int. Would it be safe to pass-ENXIOto it in this case?No, sorry, I was wrong.
So this means there are no issues with this patch. Patches 2 and 3 have already been applied by you.
I will temporarily resend only patch 1:
" watchdog: qcom: Propagate errors from optional IRQ lookup "
Best regards,
Phuc
Guenter Roeck
maintainerRe: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
Quoted 16 lines · Bui Duc Phuc
Hi Guenter,
Thank you for your feedback.
Quoted 11 lines
Quoted 11 lines
Quoted 5 lines
Quoted 2 lines
+ return irq; if (irq > 0) {This if () is no longer needed.
If we remove the if (irq > 0) check, irq can be
-ENXIOand would be passed todevm_request_irq().
I see that the irq argument ofdevm_request_irq()is an unsigned int. Would it be safe to pass-ENXIOto it in this case?
Quoted 8 lines
Quoted 2 lines
No, sorry, I was wrong.
So this means there are no issues with this patch. Patches 2 and 3 have already been applied by you.
I will temporarily resend only patch 1:
" watchdog: qcom: Propagate errors from optional IRQ lookup "
Correct. Note that gmail may swallow this reply, claiming that it is spam.
Guenter
Re: [PATCH 4/4] watchdog: aspeed: Propagate errors from optional IRQ lookup
In reply to [email protected]Quoted 10 lines · On Fri, Aug 07, 2026 at 03:16:52PM +0700, [email protected] wrote:
From: bui duc phuc <[email protected]>
platform_get_irq_optional()returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ,-ENXIOindicates that no IRQ is available, while other errors should be propagated.Propagate errors such as -EPROBE_DEFER and
-EINVALinstead of continuing probe without the IRQ.Signed-off-by bui duc phuc <[email protected]>
Applied.
Thanks,
Guenter
[email protected]
AI reviewThank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The probe function aborts and returns an invalid positive value if an optional IRQ is defined but…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The probe function aborts and returns an invalid positive value if an optional IRQ is defined but the hardware variant does not support pretimeout. --
--- Patch [1]: [PATCH 1/4] watchdog: qcom: Propagate errors from optional IRQ lookup --- commit 29f7b7cd8d0f4e915e9e20f6974535c663f1a3b4
Author: bui duc phuc <[email protected]>
watchdog: qcom: Propagate errors from optional IRQ lookup
This commit updates the error handling for an optional interrupt lookup in the Qualcomm watchdog probe. Instead of only checking for -EPROBE_DEFER, it attempts to propagate all errors except -ENXIO to better report failures.
drivers/watchdog/qcom-wdt.c static int qcom_wdt_probe(struct platform_device *pdev) · line 318
Quoted 12 lines
drivers/watchdog/qcom-wdt.c +2
-2@@ -314,8 +314,8 @@ static int qcom_wdt_probe(struct platform_device *pdev) wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout =1 ; }else { -if (irq == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (irq != -ENXIO ) +return irq;
[Severity: High]
Will this cause the probe to fail on platforms where a valid IRQ is found but pretimeout is disabled?
If platform_get_irq_optional() successfully finds an IRQ, it returns a positive number. If the platform (such as APQ8064 or IPQ8064) provides an interrupt in the device tree but the match data does not support pretimeout, qcom_wdt_probe() execution falls into this else block.
Since the positive IRQ number does not equal -ENXIO, this condition evaluates to true and the driver prematurely returns the positive IRQ number.
The driver core treats any non-zero return from probe as an error, which aborts the watchdog initialization completely leaving the system without watchdog protection.
Should this condition be scoped to only catch negative error codes, for example by checking if (irq < 0 && irq != -ENXIO) before returning?
Quoted 3 lines
drivers/watchdog/qcom-wdt.c +0
-0wdt->wdd.info = &qcom_wdt_info; }
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Guenter Roeck
maintainerQuoted 20 lines · On 8/7/26 01:16, [email protected] wrote:
From: bui duc phuc <[email protected]>
platform_get_irq_optional()returns a positive IRQ number on success or a negative error code on failure. For an optional IRQ,-ENXIOindicates that no IRQ is available, while other errors should be propagated.Instead of only checking for -EPROBE_DEFER, propagate all error codes returned by
platform_get_irq_optional()other than-ENXIO, so that failures are properly reported to the caller.Signed-off-by bui duc phuc <[email protected]>--- drivers/watchdog/qcom-wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/watchdog/qcom-wdt.c +0
-0
drivers/watchdog/qcom-wdt.c static int qcom_wdt_probe(struct platform_device *pdev) · line 302
Quoted 7 lines
drivers/watchdog/qcom-wdt.c +2
-2@@ -298,8 +298,8 @@ static int qcom_wdt_probe(struct platform_device *pdev) wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout =1 ; }else { -if (irq == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (irq != -ENXIO ) +return irq;
This is wrong. Check the if() path - the code ends up here if pretimeout == 0, even if irq > 0.
Guenter
Hi Guenter,
Thanks for the review.
Quoted 4 lines
This is wrong. Check the
if()path - the code ends up here if pretimeout == 0, even if irq > 0.
You're right. I misunderstood the condition in the if() path. I'll rewrite it as follows:
irq = platform_get_irq_optional(pdev, 0);
+if (irq < 0 && irq != -ENXIO)
+ return irq;
if (data->pretimeout && irq > 0) {
.....
} else {
- if (irq == -EPROBE_DEFER)
- return -EPROBE_DEFER;
wdt->wdd.info = &qcom_wdt_info;
}
Best regards,
Phuc
Guenter Roeck
maintainerQuoted 13 lines · Bui Duc Phuc
Hi Guenter,
Thanks for the review.
Quoted 4 lines
This is wrong. Check the
if()path - the code ends up here if pretimeout == 0, even if irq > 0.You're right. I misunderstood the condition in the
if()path. I'll rewrite it as follows:irq = platform_get_irq_optional(pdev, 0);
Review
Quoted 2 lines
(quoted diff) +2
-0+if (irq < 0 && irq != -ENXIO) + return irq;
This is still wrong. If there is no pretimeout, it does not matter if there is an error.
Guenter
Quoted 10 lines
if (
data->pretimeout&& irq > 0) {
.....
} else {
- if (irq == -EPROBE_DEFER)- return -EPROBE_DEFER; wdt->wdd.info = &qcom_wdt_info;}
Best regards,
Phuc
Hi Guenter
Thank you for your review .
Quoted 6 lines
Review
Quoted 3 lines
irq = platform_get_irq_optional(pdev, 0);(quoted diff) +2
-0+if (irq < 0 && irq != -ENXIO) + return irq;This is still wrong. If there is no pretimeout, it does not matter if there is an error.
If checking data->pretimeout is required here, I'd propose one of the following approaches
let me know which one you'd prefer:
Option A (minimal diff, keep existing structure):
---------------
irq = platform_get_irq_optional(pdev, 0);
if (data->pretimeout && irq > 0) {
ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
"wdt_bark", &wdt->wdd);
if (ret)
return ret;
wdt->wdd.info = &qcom_wdt_pt_info;
wdt->wdd.pretimeout = 1;
} else {
if (data->pretimeout && irq < 0 && irq != -ENXIO)
return irq;
wdt->wdd.info = &qcom_wdt_info;
}------------------
Option B (check moved out, before the if/else):
------------------
irq = platform_get_irq_optional(pdev, 0);
if (data->pretimeout && irq < 0 && irq != -ENXIO)
return irq;
if (data->pretimeout && irq > 0) {
ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
"wdt_bark", &wdt->wdd);
if (ret)
return ret;
wdt->wdd.info = &qcom_wdt_pt_info;
wdt->wdd.pretimeout = 1;
} else {
wdt->wdd.info = &qcom_wdt_info;
}----------------------
Option C (default-then-override, only look up the IRQ when pretimeout is supported):
----------------------wdt->wdd.info = &qcom_wdt_info;
if (data->pretimeout) {
irq = platform_get_irq_optional(pdev, 0);
if(irq < 0 && irq != -ENXIO)
return irq;
if (irq > 0){
ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
"wdt_bark", &wdt->wdd);
if(ret)
return ret;
wdt->wdd.info= &qcom_wdt_pt_info;
wdt->wdd.pretimeout = 1;
}
}-----------------------
Let me know which one you think fits best, or if you'd prefer something else.
Best regards,
Phuc
Guenter Roeck
maintainerQuoted 75 lines · Bui Duc Phuc
Hi Guenter
Thank you for your review .
Quoted 6 lines
Review
Quoted 3 lines
irq = platform_get_irq_optional(pdev, 0);(quoted diff) +2
-0+if (irq < 0 && irq != -ENXIO) + return irq;This is still wrong. If there is no pretimeout, it does not matter if there is an error.
If checking
data->pretimeoutis required here, I'd propose one of the following approaches
let me know which one you'd prefer:Option A (minimal diff, keep existing structure):
---------------
irq =platform_get_irq_optional(pdev, 0);if (data->pretimeout && irq > 0) { ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0, "wdt_bark", &wdt->wdd); if (ret) return ret; wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout = 1; } else { if (data->pretimeout && irq < 0 && irq != -ENXIO) return irq; wdt->wdd.info = &qcom_wdt_info; }------------------
Option B (check moved out, before the if/else):
------------------
irq =platform_get_irq_optional(pdev, 0);
if (data->pretimeout&& irq < 0 && irq !=-ENXIO)return irq;if (data->pretimeout && irq > 0) { ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0, "wdt_bark", &wdt->wdd); if (ret) return ret; wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout = 1; } else { wdt->wdd.info = &qcom_wdt_info; }----------------------
Option C (default-then-override, only look up the IRQ when pretimeout is supported):
----------------------
wdt->wdd.info=&qcom_wdt_info;if (data->pretimeout) { irq = platform_get_irq_optional(pdev, 0); if(irq < 0 && irq != -ENXIO) return irq; if (irq > 0){ ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0, "wdt_bark", &wdt->wdd); if(ret) return ret; wdt->wdd.info= &qcom_wdt_pt_info; wdt->wdd.pretimeout = 1; } }
Quoted 4 lines
-----------------------
Let me know which one you think fits best, or if you'd prefer something else.
I wpuld probably implement something like
if (data->pretimeout) {
irq = platform_get_irq_optional(pdev, 0);
if (irq < 0 && irq != -ENXIO)
return irq;
ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
"wdt_bark", &wdt->wdd);
if (ret)
return ret;
wdt->wdd.info = &qcom_wdt_pt_info;
wdt->wdd.pretimeout = 1;
} else {
wdt->wdd.info = &qcom_wdt_info;
}(which I think would be a combination of B and C) but ultimately it is POV and doesn't really matter.
Thanks,
Guenter
Hi Guenter,
Thank you for your feedback.
Quoted 18 lines
I wpuld probably implement something like
if (data->pretimeout) { irq = platform_get_irq_optional(pdev, 0); if (irq < 0 && irq != -ENXIO) return irq; ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0, "wdt_bark", &wdt->wdd); if (ret) return ret; wdt->wdd.info = &qcom_wdt_pt_info; wdt->wdd.pretimeout = 1; } else { wdt->wdd.info = &qcom_wdt_info; }
Quoted 3 lines
(which I think would be a combination of B and C) but ultimately it is POV and doesn't really matter.
I'll go with your suggested approach.
Best regards,
Phuc