[PATCH v2 2/2] media: rc: meson-ir: allow the receiver to wake the system
From: christian . koever-draxl
Date: Fri Nov 06 2026 - 05:23:17 EST
From: Christian Stefan Kövér-Draxl <ckoever@xxxxxxxxxx>
The suspend callback switches the decoder off, so nothing is left to
notice the remote and the receiver can never wake the system from
s2idle, where only Linux interrupts can wake the CPUs.
When the device is a wakeup source, keep the decoder running and arm
its interrupt as a wake interrupt instead. Boards without the
wakeup-source property keep the existing behaviour.
This does not affect suspend to RAM on boards whose firmware watches
the IR receiver itself while the SoC is down, as on S4 where BL31 wakes
the board on the remote's power key.
Tested on an S905W2 board in s2idle: the power key on the remote wakes
it; with wakeup disabled for the receiver it does not.
Signed-off-by: Christian Stefan Kövér-Draxl <ckoever@xxxxxxxxxx>
---
drivers/media/rc/meson-ir.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 272ebb0d97c8..6b5b5f71a1b4 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -165,6 +165,7 @@ struct meson_ir {
const struct meson_ir_param *param;
struct regmap *reg;
struct rc_dev *rc;
+ int irq;
spinlock_t lock;
};
@@ -475,6 +476,8 @@ static int meson_ir_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ ir->irq = irq;
+
if (ir->param->support_hw_decoder)
ir->rc = devm_rc_allocate_device(&pdev->dev,
RC_DRIVER_SCANCODE);
@@ -523,6 +526,8 @@ static int meson_ir_probe(struct platform_device *pdev)
return ret;
}
+ device_init_wakeup(dev, of_property_read_bool(node, "wakeup-source"));
+
dev_info(dev, "receiver initialized\n");
return 0;
@@ -571,6 +576,9 @@ static __maybe_unused int meson_ir_resume(struct device *dev)
{
struct meson_ir *ir = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev))
+ disable_irq_wake(ir->irq);
+
if (ir->param->support_hw_decoder)
meson_ir_hw_decoder_init(ir->rc, &ir->rc->enabled_protocols);
else
@@ -584,6 +592,15 @@ static __maybe_unused int meson_ir_suspend(struct device *dev)
struct meson_ir *ir = dev_get_drvdata(dev);
unsigned long flags;
+ /*
+ * Leave the receiver running when it is meant to wake the system up,
+ * otherwise there is nothing left to notice the remote.
+ */
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(ir->irq);
+ return 0;
+ }
+
spin_lock_irqsave(&ir->lock, flags);
regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0);
spin_unlock_irqrestore(&ir->lock, flags);
--
2.56.0