Alejandro González wrote: > This patch allows userspace to set up wakeup alarms on any RTC handled by the > sun6i driver, and adds the necessary PM operations to allow resuming from > suspend when the configured wakeup alarm fires a IRQ. Of course, that the > device actually resumes depends on the suspend state and how a particular > hardware reacts to it, but that is out of scope for this patch. > > I've tested these changes on a Pine H64 model B, which contains a > Allwinner H6 SoC, with the help of CONFIG_PM_TEST_SUSPEND kernel option. > These are the interesting outputs from the kernel and commands which > show that it works. As every RTC handled by this driver is largely the > same, I think that it shouldn't introduce any regression on other SoCs, > but I may be wrong. > > [ 1.092705] PM: test RTC wakeup from 'freeze' suspend > [ 1.098230] PM: suspend entry (s2idle) > [ 1.212907] PM: suspend devices took 0.080 seconds > (The SoC freezes for some seconds) > [ 3.197604] PM: resume devices took 0.104 seconds > [ 3.215937] PM: suspend exit > > [ 1.092812] PM: test RTC wakeup from 'mem' suspend > [ 1.098089] PM: suspend entry (deep) > [ 1.102033] PM: suspend exit > [ 1.105205] PM: suspend test failed, error -22 > > In any case, the RTC alarm interrupt gets fired as exptected: > > $ echo +5 > /sys/class/rtc/rtc0/wakealarm && sleep 5 && grep rtc /proc/interrupts > 29: 1 0 0 0 GICv2 133 Level 7000000.rtc > > Signed-off-by: Alejandro González <alejandro.gonzalez.correo@xxxxxxxxx> > --- > drivers/rtc/rtc-sun6i.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c > index c0e75c373605..b7611e5dea3f 100644 > --- a/drivers/rtc/rtc-sun6i.c > +++ b/drivers/rtc/rtc-sun6i.c > @@ -598,6 +598,33 @@ static const struct rtc_class_ops sun6i_rtc_ops = { > .alarm_irq_enable = sun6i_rtc_alarm_irq_enable > }; > > +#ifdef CONFIG_PM_SLEEP > +/* Enable IRQ wake on suspend, to wake up from RTC. */ > +static int sun6i_rtc_suspend(struct device *dev) > +{ > + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); > + > + if (device_may_wakeup(dev)) > + enable_irq_wake(chip->irq); > + > + return 0; > +} > + > +/* Disable IRQ wake on resume. */ > +static int sun6i_rtc_resume(struct device *dev) > +{ > + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); > + > + if (device_may_wakeup(dev)) > + disable_irq_wake(chip->irq); > + > + return 0; > +} > +#endif > + > +static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops, > + sun6i_rtc_suspend, sun6i_rtc_resume); > + > static int sun6i_rtc_probe(struct platform_device *pdev) > { > struct sun6i_rtc_dev *chip = sun6i_rtc; > @@ -650,6 +677,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev) > > clk_prepare_enable(chip->losc); > > + device_init_wakeup(&pdev->dev, 1); > + > chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i", > &sun6i_rtc_ops, THIS_MODULE); > if (IS_ERR(chip->rtc)) { > @@ -684,6 +713,7 @@ static struct platform_driver sun6i_rtc_driver = { > .driver = { > .name = "sun6i-rtc", > .of_match_table = sun6i_rtc_dt_ids, > + .pm = &sun6i_rtc_pm_ops, > }, > }; > builtin_platform_driver(sun6i_rtc_driver); > I'd be grateful if someone can test this patch on different boards to the Pine H64 model B. I'm afraid that board is the only one I have to test this. Regards.