]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
rtc: pm8xxx: implement qcom,no-alarm flag for non-HLOS owned alarm
authorJonathan Marek <jonathan@marek.ca>
Wed, 19 Feb 2025 13:41:16 +0000 (14:41 +0100)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Mon, 17 Mar 2025 13:34:06 +0000 (14:34 +0100)
Qualcomm x1e80100 firmware sets the ownership of the RTC alarm to ADSP.
Thus writing to RTC alarm registers and receiving alarm interrupts is not
possible.

Add a qcom,no-alarm flag to support RTC on this platform.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Link: https://lore.kernel.org/r/20241015004945.3676-2-jonathan@marek.ca
[ johan: drop no_alarm flag and restructure probe() ]
Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
Tested-by: Steev Klimaszewski <steev@kali.org>
Tested-by: Joel Stanley <joel@jms.id.au>
Tested-by: Sebastian Reichel <sre@kernel.org> # Lenovo T14s Gen6
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20250219134118.31017-5-johan+linaro@kernel.org
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/rtc/rtc-pm8xxx.c

index a547729d28773c220a5bc28005905413f3cefc62..3c1dddcc81df36da8cd27e4dd4b828e3091df780 100644 (file)
@@ -606,9 +606,11 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
        if (!rtc_dd->regmap)
                return -ENXIO;
 
-       rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
-       if (rtc_dd->alarm_irq < 0)
-               return -ENXIO;
+       if (!of_property_read_bool(pdev->dev.of_node, "qcom,no-alarm")) {
+               rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
+               if (rtc_dd->alarm_irq < 0)
+                       return -ENXIO;
+       }
 
        rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node,
                                                      "allow-set-time");
@@ -624,8 +626,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc_dd);
 
-       devm_device_init_wakeup(&pdev->dev);
-
        rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
        if (IS_ERR(rtc_dd->rtc))
                return PTR_ERR(rtc_dd->rtc);
@@ -633,16 +633,22 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
        rtc_dd->rtc->ops = &pm8xxx_rtc_ops;
        rtc_dd->rtc->range_max = U32_MAX;
 
-       rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq,
-                                         pm8xxx_alarm_trigger,
-                                         IRQF_TRIGGER_RISING,
-                                         "pm8xxx_rtc_alarm", rtc_dd);
-       if (rc < 0)
-               return rc;
+       if (rtc_dd->alarm_irq) {
+               rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq,
+                                                 pm8xxx_alarm_trigger,
+                                                 IRQF_TRIGGER_RISING,
+                                                 "pm8xxx_rtc_alarm", rtc_dd);
+               if (rc < 0)
+                       return rc;
 
-       rc = devm_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
-       if (rc)
-               return rc;
+               rc = devm_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
+               if (rc)
+                       return rc;
+
+               devm_device_init_wakeup(&pdev->dev);
+       } else {
+               clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
+       }
 
        return devm_rtc_register_device(rtc_dd->rtc);
 }