* [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source
2026-09-29 12:02 [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Linus Walleij
@ 2026-09-29 12:02 ` Linus Walleij
2026-10-07 9:28 ` Dan Scally
2026-09-29 12:02 ` [PATCH 2/3] media: mali-c55: Keep IRQ requested during suspend Linus Walleij
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2026-09-29 12:02 UTC (permalink / raw)
To: Li Youhong, Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev
Cc: linux-media, devicetree, linux-kernel, Linus Walleij
The Mali-C55 interrupt can be wired as a wake source on platforms that
support it. Use the standard wakeup-source property.
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
Documentation/devicetree/bindings/media/arm,mali-c55.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
index fc4fcd19922a..acd57799ccd0 100644
--- a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
+++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
@@ -20,6 +20,8 @@ properties:
interrupts:
maxItems: 1
+ wakeup-source: true
+
clocks:
items:
- description: ISP Video Clock
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source
2026-09-29 12:02 ` [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source Linus Walleij
@ 2026-10-07 9:28 ` Dan Scally
2026-10-08 13:22 ` Linus Walleij
0 siblings, 1 reply; 9+ messages in thread
From: Dan Scally @ 2026-10-07 9:28 UTC (permalink / raw)
To: Linus Walleij, Li Youhong, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev
Cc: linux-media, devicetree, linux-kernel
Hi Linus, thanks for the patchset
On 29/09/2026 13:02, Linus Walleij wrote:
> The Mali-C55 interrupt can be wired as a wake source on platforms that
> support it. Use the standard wakeup-source property.
That's interesting! How's that work, though? In the RZ/V2H particularly the ISP is in an offline
mode, so I'm struggling to see how one could trigger the interrupt whilst the device is suspended,
since you'd need to instruct the IVC to queue a frame.
Thanks
Dan
> Assisted-by: LLM
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> Documentation/devicetree/bindings/media/arm,mali-c55.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> index fc4fcd19922a..acd57799ccd0 100644
> --- a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> @@ -20,6 +20,8 @@ properties:
> interrupts:
> maxItems: 1
>
> + wakeup-source: true
> +
> clocks:
> items:
> - description: ISP Video Clock
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source
2026-10-07 9:28 ` Dan Scally
@ 2026-10-08 13:22 ` Linus Walleij
0 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2026-10-08 13:22 UTC (permalink / raw)
To: Dan Scally
Cc: Li Youhong, Jacopo Mondi, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Hans Verkuil, Nayden Kanchev,
linux-media, devicetree, linux-kernel
On Wed, Oct 7, 2026 at 11:29 AM Dan Scally <dan.scally@ideasonboard.com> wrote:
> On 29/09/2026 13:02, Linus Walleij wrote:
> > The Mali-C55 interrupt can be wired as a wake source on platforms that
> > support it. Use the standard wakeup-source property.
>
> That's interesting! How's that work, though? In the RZ/V2H particularly the ISP is in an offline
> mode, so I'm struggling to see how one could trigger the interrupt whilst the device is suspended,
> since you'd need to instruct the IVC to queue a frame.
The implementation is IP-neutral and doesn't really ask this question.
The typical silicon solution would be if the IP was synthesized into
and always-on power domain on the chip. This means the CPU
which runs Linux is powered off, while the ISP is still powered
on, and could generate a wakeup IRQ. This is how e.g. GPIO
units that can wake up the system work: they are always
powered in some sense.
I don't know if that makes any *sense* from a system engineering
point of view, but it is something that can be done.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] media: mali-c55: Keep IRQ requested during suspend
2026-09-29 12:02 [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Linus Walleij
2026-09-29 12:02 ` [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source Linus Walleij
@ 2026-09-29 12:02 ` Linus Walleij
2026-10-07 10:12 ` Dan Scally
2026-09-29 12:02 ` [PATCH 3/3] media: mali-c55: Keep ISP powered while IRQ wake is armed Linus Walleij
2026-10-06 11:43 ` [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Lad, Prabhakar
3 siblings, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2026-09-29 12:02 UTC (permalink / raw)
To: Li Youhong, Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev
Cc: linux-media, devicetree, linux-kernel, Linus Walleij, stable
The interrupt is currently freed on every runtime suspend and requested
again on runtime resume. Apart from tying interrupt ownership to the
power state rather than to the driver lifetime, this leaves remove to
guess whether an action is installed for the IRQ.
Request the interrupt once during probe and free it during remove.
Disable and synchronize the IRQ before powering the ISP off, and enable
it only after a successful power-on.
Hold a runtime PM reference during probe until the IRQ is installed,
and stop runtime PM and drain the IRQ before unregistering the media
entities during remove.
If firmware marks the ISP as a wakeup source, initialize device wakeup
and enable IRQ wake during system suspend. Disable it again before
resuming the device.
This configures the interrupt controller wake path.
Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
.../media/platform/arm/mali-c55/mali-c55-core.c | 84 ++++++++++++++++------
1 file changed, 64 insertions(+), 20 deletions(-)
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
index f28e9f4354ac..07267b79801b 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
@@ -17,6 +17,8 @@
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_wakeup.h>
+#include <linux/property.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -675,8 +677,7 @@ static int __maybe_unused mali_c55_runtime_suspend(struct device *dev)
{
struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
- if (irq_has_action(mali_c55->irqnum))
- free_irq(mali_c55->irqnum, dev);
+ disable_irq(mali_c55->irqnum);
__mali_c55_power_off(mali_c55);
return 0;
@@ -745,25 +746,41 @@ static int __maybe_unused mali_c55_runtime_resume(struct device *dev)
if (ret)
return ret;
- /*
- * The driver needs to transfer large amounts of register settings to
- * the ISP each frame, using either a DMA transfer or memcpy. We use a
- * threaded IRQ to avoid disabling interrupts the entire time that's
- * happening.
- */
- ret = request_threaded_irq(mali_c55->irqnum, NULL, mali_c55_isr,
- IRQF_ONESHOT, dev_driver_string(dev), dev);
- if (ret) {
- __mali_c55_power_off(mali_c55);
- dev_err(dev, "failed to request irq\n");
+ enable_irq(mali_c55->irqnum);
+
+ return 0;
+}
+
+static int __maybe_unused mali_c55_suspend(struct device *dev)
+{
+ struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
+ int ret;
+
+ if (device_may_wakeup(dev)) {
+ ret = enable_irq_wake(mali_c55->irqnum);
+ if (ret)
+ return ret;
}
+ ret = pm_runtime_force_suspend(dev);
+ if (ret && device_may_wakeup(dev))
+ disable_irq_wake(mali_c55->irqnum);
+
return ret;
}
+static int __maybe_unused mali_c55_resume(struct device *dev)
+{
+ struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(mali_c55->irqnum);
+
+ return pm_runtime_force_resume(dev);
+}
+
static const struct dev_pm_ops mali_c55_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
- pm_runtime_force_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(mali_c55_suspend, mali_c55_resume)
SET_RUNTIME_PM_OPS(mali_c55_runtime_suspend, mali_c55_runtime_resume,
NULL)
};
@@ -825,27 +842,53 @@ static int mali_c55_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
+ pm_runtime_get_noresume(dev);
pm_runtime_enable(&pdev->dev);
ret = mali_c55_media_frameworks_init(mali_c55);
if (ret)
goto err_pm_runtime_disable;
- pm_runtime_idle(&pdev->dev);
-
mali_c55->irqnum = platform_get_irq(pdev, 0);
if (mali_c55->irqnum < 0) {
ret = mali_c55->irqnum;
goto err_deinit_media_frameworks;
}
+ /*
+ * The driver needs to transfer large amounts of register settings to
+ * the ISP each frame, using either a DMA transfer or memcpy. We use a
+ * threaded IRQ to avoid disabling interrupts the entire time that's
+ * happening.
+ */
+ ret = request_threaded_irq(mali_c55->irqnum, NULL, mali_c55_isr,
+ IRQF_ONESHOT, dev_driver_string(dev), dev);
+ if (ret) {
+ dev_err(dev, "failed to request irq\n");
+ goto err_deinit_media_frameworks;
+ }
+
+ if (device_property_read_bool(dev, "wakeup-source")) {
+ ret = devm_device_init_wakeup(dev);
+ if (ret) {
+ ret = dev_err_probe(dev, ret,
+ "failed to initialize wakeup\n");
+ goto err_free_irq;
+ }
+ }
+
+ pm_runtime_put_autosuspend(dev);
+
return 0;
+err_free_irq:
+ free_irq(mali_c55->irqnum, dev);
err_deinit_media_frameworks:
mali_c55_media_frameworks_deinit(mali_c55);
err_pm_runtime_disable:
- pm_runtime_set_suspended(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_set_suspended(&pdev->dev);
kfree(mali_c55->context.registers);
err_power_off:
__mali_c55_power_off(mali_c55);
@@ -859,12 +902,13 @@ static void mali_c55_remove(struct platform_device *pdev)
{
struct mali_c55 *mali_c55 = platform_get_drvdata(pdev);
+ pm_runtime_disable(&pdev->dev);
+ free_irq(mali_c55->irqnum, &pdev->dev);
mali_c55_media_frameworks_deinit(mali_c55);
- if (!pm_runtime_suspended(&pdev->dev)) {
+ if (!pm_runtime_status_suspended(&pdev->dev)) {
__mali_c55_power_off(mali_c55);
pm_runtime_set_suspended(&pdev->dev);
}
- pm_runtime_disable(&pdev->dev);
kfree(mali_c55->context.registers);
of_reserved_mem_device_release(&pdev->dev);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 2/3] media: mali-c55: Keep IRQ requested during suspend
2026-09-29 12:02 ` [PATCH 2/3] media: mali-c55: Keep IRQ requested during suspend Linus Walleij
@ 2026-10-07 10:12 ` Dan Scally
0 siblings, 0 replies; 9+ messages in thread
From: Dan Scally @ 2026-10-07 10:12 UTC (permalink / raw)
To: Linus Walleij, Li Youhong, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev
Cc: linux-media, devicetree, linux-kernel, stable
Hi Linus
On 29/09/2026 13:02, Linus Walleij wrote:
> The interrupt is currently freed on every runtime suspend and requested
> again on runtime resume. Apart from tying interrupt ownership to the
> power state rather than to the driver lifetime, this leaves remove to
> guess whether an action is installed for the IRQ.
>
> Request the interrupt once during probe and free it during remove.
>
> Disable and synchronize the IRQ before powering the ISP off, and enable
> it only after a successful power-on.
>
> Hold a runtime PM reference during probe until the IRQ is installed,
> and stop runtime PM and drain the IRQ before unregistering the media
> entities during remove.
>
> If firmware marks the ISP as a wakeup source, initialize device wakeup
> and enable IRQ wake during system suspend. Disable it again before
> resuming the device.
I think that adding this could be a separate commit to fixing the irq handling...and perhaps that
should be the case given the Fixes tag?
>
> This configures the interrupt controller wake path.
>
> Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> .../media/platform/arm/mali-c55/mali-c55-core.c | 84 ++++++++++++++++------
> 1 file changed, 64 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
> index f28e9f4354ac..07267b79801b 100644
> --- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c
> +++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
> @@ -17,6 +17,8 @@
> #include <linux/of_reserved_mem.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> +#include <linux/pm_wakeup.h>
> +#include <linux/property.h>
> #include <linux/reset.h>
> #include <linux/slab.h>
> #include <linux/string.h>
> @@ -675,8 +677,7 @@ static int __maybe_unused mali_c55_runtime_suspend(struct device *dev)
> {
> struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
>
> - if (irq_has_action(mali_c55->irqnum))
> - free_irq(mali_c55->irqnum, dev);
> + disable_irq(mali_c55->irqnum);
> __mali_c55_power_off(mali_c55);
>
> return 0;
> @@ -745,25 +746,41 @@ static int __maybe_unused mali_c55_runtime_resume(struct device *dev)
> if (ret)
> return ret;
>
> - /*
> - * The driver needs to transfer large amounts of register settings to
> - * the ISP each frame, using either a DMA transfer or memcpy. We use a
> - * threaded IRQ to avoid disabling interrupts the entire time that's
> - * happening.
> - */
> - ret = request_threaded_irq(mali_c55->irqnum, NULL, mali_c55_isr,
> - IRQF_ONESHOT, dev_driver_string(dev), dev);
> - if (ret) {
> - __mali_c55_power_off(mali_c55);
> - dev_err(dev, "failed to request irq\n");
> + enable_irq(mali_c55->irqnum);
> +
> + return 0;
> +}
> +
> +static int __maybe_unused mali_c55_suspend(struct device *dev)
> +{
> + struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
> + int ret;
> +
> + if (device_may_wakeup(dev)) {
> + ret = enable_irq_wake(mali_c55->irqnum);
> + if (ret)
> + return ret;
> }
>
> + ret = pm_runtime_force_suspend(dev);
> + if (ret && device_may_wakeup(dev))
> + disable_irq_wake(mali_c55->irqnum);
> +
> return ret;
> }
>
> +static int __maybe_unused mali_c55_resume(struct device *dev)
> +{
> + struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
> +
> + if (device_may_wakeup(dev))
> + disable_irq_wake(mali_c55->irqnum);
> +
> + return pm_runtime_force_resume(dev);
> +}
> +
> static const struct dev_pm_ops mali_c55_pm_ops = {
> - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> - pm_runtime_force_resume)
> + SET_SYSTEM_SLEEP_PM_OPS(mali_c55_suspend, mali_c55_resume)
> SET_RUNTIME_PM_OPS(mali_c55_runtime_suspend, mali_c55_runtime_resume,
> NULL)
> };
> @@ -825,27 +842,53 @@ static int mali_c55_probe(struct platform_device *pdev)
> pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
> pm_runtime_use_autosuspend(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> + pm_runtime_get_noresume(dev);
> pm_runtime_enable(&pdev->dev);
>
> ret = mali_c55_media_frameworks_init(mali_c55);
> if (ret)
> goto err_pm_runtime_disable;
>
> - pm_runtime_idle(&pdev->dev);
> -
> mali_c55->irqnum = platform_get_irq(pdev, 0);
> if (mali_c55->irqnum < 0) {
> ret = mali_c55->irqnum;
> goto err_deinit_media_frameworks;
> }
>
> + /*
> + * The driver needs to transfer large amounts of register settings to
> + * the ISP each frame, using either a DMA transfer or memcpy. We use a
> + * threaded IRQ to avoid disabling interrupts the entire time that's
> + * happening.
> + */
> + ret = request_threaded_irq(mali_c55->irqnum, NULL, mali_c55_isr,
> + IRQF_ONESHOT, dev_driver_string(dev), dev);
> + if (ret) {
> + dev_err(dev, "failed to request irq\n");
> + goto err_deinit_media_frameworks;
> + }
> +
> + if (device_property_read_bool(dev, "wakeup-source")) {
> + ret = devm_device_init_wakeup(dev);
> + if (ret) {
> + ret = dev_err_probe(dev, ret,
> + "failed to initialize wakeup\n");
> + goto err_free_irq;
> + }
> + }
> +
> + pm_runtime_put_autosuspend(dev);
> +
> return 0;
>
> +err_free_irq:
> + free_irq(mali_c55->irqnum, dev);
> err_deinit_media_frameworks:
> mali_c55_media_frameworks_deinit(mali_c55);
> err_pm_runtime_disable:
> - pm_runtime_set_suspended(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> + pm_runtime_put_noidle(dev);
> + pm_runtime_set_suspended(&pdev->dev);
I would say that this re-ordering of the pm_runtime_set_suspended() and pm_runtime_disable() calls
probably ought to be in a separate commit too, since it's a distinct change that should be
backported to fix stable branches.
Thanks
Dan
> kfree(mali_c55->context.registers);
> err_power_off:
> __mali_c55_power_off(mali_c55);
> @@ -859,12 +902,13 @@ static void mali_c55_remove(struct platform_device *pdev)
> {
> struct mali_c55 *mali_c55 = platform_get_drvdata(pdev);
>
> + pm_runtime_disable(&pdev->dev);
> + free_irq(mali_c55->irqnum, &pdev->dev);
> mali_c55_media_frameworks_deinit(mali_c55);
> - if (!pm_runtime_suspended(&pdev->dev)) {
> + if (!pm_runtime_status_suspended(&pdev->dev)) {
> __mali_c55_power_off(mali_c55);
> pm_runtime_set_suspended(&pdev->dev);
> }
> - pm_runtime_disable(&pdev->dev);
> kfree(mali_c55->context.registers);
> of_reserved_mem_device_release(&pdev->dev);
> }
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] media: mali-c55: Keep ISP powered while IRQ wake is armed
2026-09-29 12:02 [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Linus Walleij
2026-09-29 12:02 ` [PATCH 1/3] dt-bindings: media: mali-c55: Allow wakeup source Linus Walleij
2026-09-29 12:02 ` [PATCH 2/3] media: mali-c55: Keep IRQ requested during suspend Linus Walleij
@ 2026-09-29 12:02 ` Linus Walleij
2026-10-06 11:43 ` [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Lad, Prabhakar
3 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2026-09-29 12:02 UTC (permalink / raw)
To: Li Youhong, Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev
Cc: linux-media, devicetree, linux-kernel, Linus Walleij
System suspend enables IRQ wake and then calls pm_runtime_force_suspend().
For an active ISP this asserts its resets and disables its clocks, so it
can no longer generate frame interrupts. An already runtime-suspended ISP
is left powered off as well.
Take a runtime PM reference before arming IRQ wake and retain it until
resume. This powers up an idle ISP and keeps an active ISP's configuration
intact. Release the reference if arming wake fails, and use the PM wake
policy in both suspend and resume to balance the reference. Continue to
use forced runtime suspend and resume when wake is disabled.
Use the forced power-down path for hibernation freeze and power-off even
when wake is enabled. Capture must not remain active while a hibernation
image is created.
Wake events require a configured stream and an input source that
remains operational during system sleep.
The internal TPG shares the ISP's power state. External sensor and
receiver drivers will need their own system-sleep wake support.
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
.../media/platform/arm/mali-c55/mali-c55-core.c | 38 ++++++++++++++--------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
index 07267b79801b..2629bb3aa628 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
@@ -756,31 +756,43 @@ static int __maybe_unused mali_c55_suspend(struct device *dev)
struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
int ret;
- if (device_may_wakeup(dev)) {
- ret = enable_irq_wake(mali_c55->irqnum);
- if (ret)
- return ret;
- }
+ if (!device_may_wakeup(dev))
+ return pm_runtime_force_suspend(dev);
- ret = pm_runtime_force_suspend(dev);
- if (ret && device_may_wakeup(dev))
- disable_irq_wake(mali_c55->irqnum);
+ /* Keep the ISP clocked and out of reset while it can wake the system. */
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return ret;
- return ret;
+ ret = enable_irq_wake(mali_c55->irqnum);
+ if (ret) {
+ pm_runtime_put_autosuspend(dev);
+ return ret;
+ }
+
+ return 0;
}
static int __maybe_unused mali_c55_resume(struct device *dev)
{
struct mali_c55 *mali_c55 = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
- disable_irq_wake(mali_c55->irqnum);
+ if (!device_may_wakeup(dev))
+ return pm_runtime_force_resume(dev);
- return pm_runtime_force_resume(dev);
+ disable_irq_wake(mali_c55->irqnum);
+ pm_runtime_put_autosuspend(dev);
+
+ return 0;
}
static const struct dev_pm_ops mali_c55_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(mali_c55_suspend, mali_c55_resume)
+ .suspend = pm_sleep_ptr(mali_c55_suspend),
+ .resume = pm_sleep_ptr(mali_c55_resume),
+ .freeze = pm_sleep_ptr(pm_runtime_force_suspend),
+ .thaw = pm_sleep_ptr(pm_runtime_force_resume),
+ .poweroff = pm_sleep_ptr(pm_runtime_force_suspend),
+ .restore = pm_sleep_ptr(pm_runtime_force_resume),
SET_RUNTIME_PM_OPS(mali_c55_runtime_suspend, mali_c55_runtime_resume,
NULL)
};
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling
2026-09-29 12:02 [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Linus Walleij
` (2 preceding siblings ...)
2026-09-29 12:02 ` [PATCH 3/3] media: mali-c55: Keep ISP powered while IRQ wake is armed Linus Walleij
@ 2026-10-06 11:43 ` Lad, Prabhakar
2026-10-08 9:26 ` Linus Walleij
3 siblings, 1 reply; 9+ messages in thread
From: Lad, Prabhakar @ 2026-10-06 11:43 UTC (permalink / raw)
To: Linus Walleij
Cc: Li Youhong, Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev, linux-media, devicetree, linux-kernel, stable
Hi Linus,
On Tue, Sep 29, 2026 at 1:08 PM Linus Walleij <linusw@kernel.org> wrote:
>
> This is essentially my reply with the "proper fix" for:
> https://lore.kernel.org/linux-media/20260903025526.2657105-1-dayou5941@163.com/
>
> Keep the Mali-C55 interrupt requested for the driver's lifetime instead
> of changing interrupt ownership along with the runtime power state.
> Synchronize and disable the IRQ before power-off, and enable it after
> power-on. Hold a PM reference until probe installs the IRQ, and stop
> runtime PM and drain the IRQ before removing the media entities.
>
> Allow platforms to mark the ISP as a wakeup source. Hold a runtime PM
> reference while IRQ wake is armed, resuming an idle ISP if needed and
> preserving an active ISP's configuration. Balance the reference on resume
> and failure. Hibernation still uses the power-down path.
>
> Wake events require a configured stream and an input that remains active
> during system sleep. The internal TPG shares the ISP's power state;
> external sensors and receivers need their own wake support. An idle
> pipeline is not started by this series. Hardware wake remains untested.
>
> The first patch extends the binding with the standard wakeup-source
> property. The second patch updates the driver IRQ and PM handling. The
> third patch retains ISP power while IRQ wake is armed.
>
> Tested on the Renesas RZ/V2H board with the other in-flight patches
> (DTS changes and the TPG enablement) doing full suspend/resume cycles
> with wakeup from RTC and NMI and capturing images before and
> after the test.
>
Can you please share the dependency patches or branch, as these don't
apply cleanly. I tried the latest 'next' and 'media/next' branches
with no luck.
Cheers,
Prabhakar
> Assisted-by: LLM
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> Linus Walleij (3):
> dt-bindings: media: mali-c55: Allow wakeup source
> media: mali-c55: Keep IRQ requested during suspend
> media: mali-c55: Keep ISP powered while IRQ wake is armed
>
> .../devicetree/bindings/media/arm,mali-c55.yaml | 2 +
> .../media/platform/arm/mali-c55/mali-c55-core.c | 96 +++++++++++++++++-----
> 2 files changed, 78 insertions(+), 20 deletions(-)
> ---
> base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
> change-id: 20260918-mali-c55-irq-supend-resume-30b507a20011
>
> Best regards,
> --
> Linus Walleij <linusw@kernel.org>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling
2026-10-06 11:43 ` [PATCH 0/3] media: mali-c55: Fix IRQ lifetime and wake handling Lad, Prabhakar
@ 2026-10-08 9:26 ` Linus Walleij
0 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2026-10-08 9:26 UTC (permalink / raw)
To: Lad, Prabhakar
Cc: Li Youhong, Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Nayden Kanchev, linux-media, devicetree, linux-kernel, stable
On Tue, Oct 6, 2026 at 1:43 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
> Can you please share the dependency patches or branch, as these don't
> apply cleanly. I tried the latest 'next' and 'media/next' branches
> with no luck.
They are just based on a clean v7.3-rc1 from Torvalds:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=b4/mali-c55-irq-supend-resume
I can rebase on media/next and resend if that's desirable?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 9+ messages in thread