Linux RTC
 help / color / mirror / Atom feed
* [PATCH v2] rtc: pcf2127: arm the alarm IRQ as a wake IRQ
@ 2026-10-21  6:44 Aristo Chen
  2026-10-21  6:51 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Aristo Chen @ 2026-10-21  6:44 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: linux-rtc, linux-kernel, Liam Beguin, Bruno Thomsen, Aristo Chen

When an alarm IRQ is available, the driver calls device_init_wakeup(),
so the RTC shows up as wakeup capable and enabled, but it never marks
the IRQ itself as a wakeup interrupt. The PM core therefore disables
the IRQ for the whole system suspend, and the alarm cannot wake the
system: "rtcwake -m mem" on this RTC only resumes once another wakeup
source fires.

On the i.MX93 11x11 FRDM board the PCF2131 alarm is routed through a
PCAL6524 GPIO expander. Without a wakeup request on the expander pin,
the expander's own interrupt is not armed for wakeup either, so the
alarm never reaches the CPU. The BBNSM RTC on the same board uses
devm_pm_set_wake_irq() and wakes the system as expected.

Register the alarm IRQ with devm_pm_set_wake_irq() so that the PM core
arms it whenever the device may wake the system. A failure is not
fatal: the RTC keeps working, only wakeup from it is unavailable.

The I2C core already sets up the wake IRQ before probe for clients
flagged I2C_CLIENT_WAKE, which a "wakeup-source" DT property or a
wake-capable ACPI interrupt sets. Those boards can already wake from
the alarm, so skip the call for them: a second registration would only
trigger a "wake irq already initialized" warning.

Fixes: 8a914bac44be ("rtc: pcf2127: add alarm support")
Assisted-by: LLM
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
---
Changes in v2:
- Skip devm_pm_set_wake_irq() for I2C clients flagged I2C_CLIENT_WAKE,
  as the I2C core has already set up their wake IRQ (Sashiko review).

v1: https://lore.kernel.org/linux-rtc/20261020125124.1097546-1-aristo.chen@canonical.com/

Tested on an i.MX93 FRDM board, where the PCF2131 INTA reaches the SoC
through a PCAL6524 GPIO expander. The board ran an Ubuntu 6.8 kernel
with devm_pm_set_wake_irq() (fd8318a32573) and tcpci wakeup support
(a5d2edb2c9fa) backported. With this patch, the PCF2131 alarm wakes the
board from suspend-to-RAM and from s2idle, also after unbinding and
rebinding the driver. Without it, the alarm doesn't wake the board from
suspend-to-RAM.

To cover the I2C_CLIENT_WAKE path, a test module set the flag on the
client before the driver was rebound, as a "wakeup-source" property
would. The I2C core then set up the wake IRQ, the driver skipped its
own call, no "wake irq already initialized" warning appeared, and the
alarm still woke the board from suspend-to-RAM and from s2idle.

Compile-tested on rtc-next (arm64 defconfig plus RTC_DRV_PCF2127, W=1).

 drivers/rtc/rtc-pcf2127.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index ff2023908..b9ff52630 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -27,6 +27,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/watchdog.h>
 
@@ -1188,7 +1189,8 @@ static int pcf2127_configure_interrupt_pins(struct device *dev)
 }
 
 static int pcf2127_probe(struct device *dev, struct regmap *regmap,
-			 int alarm_irq, const struct pcf21xx_config *config)
+			 int alarm_irq, bool bus_wake_irq,
+			 const struct pcf21xx_config *config)
 {
 	struct pcf2127 *pcf2127;
 	int ret = 0;
@@ -1251,6 +1253,13 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
 	if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
 		device_init_wakeup(dev, true);
 		set_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features);
+
+		/* Skip if the bus code has already set the wake IRQ */
+		if (alarm_irq > 0 && !bus_wake_irq) {
+			ret = devm_pm_set_wake_irq(dev, alarm_irq);
+			if (ret)
+				dev_warn(dev, "failed to set wake IRQ: %d\n", ret);
+		}
 	}
 
 	if (pcf2127->cfg->has_int_a_b) {
@@ -1478,7 +1487,9 @@ static int pcf2127_i2c_probe(struct i2c_client *client)
 		return PTR_ERR(regmap);
 	}
 
-	return pcf2127_probe(&client->dev, regmap, client->irq, variant);
+	/* With I2C_CLIENT_WAKE, the I2C core has already set the wake IRQ */
+	return pcf2127_probe(&client->dev, regmap, client->irq,
+			     client->flags & I2C_CLIENT_WAKE, variant);
 }
 
 static struct i2c_driver pcf2127_i2c_driver = {
@@ -1555,7 +1566,7 @@ static int pcf2127_spi_probe(struct spi_device *spi)
 		return PTR_ERR(regmap);
 	}
 
-	return pcf2127_probe(&spi->dev, regmap, spi->irq, variant);
+	return pcf2127_probe(&spi->dev, regmap, spi->irq, false, variant);
 }
 
 static const struct spi_device_id pcf2127_spi_id[] = {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-21  6:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-21  6:44 [PATCH v2] rtc: pcf2127: arm the alarm IRQ as a wake IRQ Aristo Chen
2026-10-21  6:51 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox