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>
---
drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index c32fba550c8e0..1e78939625622 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -61,6 +61,7 @@ struct pm8xxx_rtc {
struct rtc_device *rtc;
struct regmap *regmap;
bool allow_set_time;
+ bool no_alarm;
int alarm_irq;
const struct pm8xxx_rtc_regs *regs;
struct device *dev;
@@ -473,9 +474,14 @@ 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;
+ rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
+ "qcom,no-alarm");
+
+ if (!rtc_dd->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");
@@ -503,7 +509,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc_dd);
- device_init_wakeup(&pdev->dev, 1);
+ if (!rtc_dd->no_alarm)
+ device_init_wakeup(&pdev->dev, 1);
rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc_dd->rtc))
@@ -512,27 +519,36 @@ 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->no_alarm) {
+ 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_rtc_register_device(rtc_dd->rtc);
if (rc)
return rc;
- rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
- if (rc)
- return rc;
+ if (!rtc_dd->no_alarm) {
+ rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
+ if (rc)
+ return rc;
+ } else {
+ clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
+ }
return 0;
}
static void pm8xxx_remove(struct platform_device *pdev)
{
- dev_pm_clear_wake_irq(&pdev->dev);
+ struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev);
+
+ if (!rtc_dd->no_alarm)
+ dev_pm_clear_wake_irq(&pdev->dev);
}
static struct platform_driver pm8xxx_rtc_driver = {
--
2.45.1
On Mon, Oct 14, 2024 at 08:47:26PM -0400, Jonathan Marek wrote:
> 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.
An alternative may be to drop the alarm interrupt from DT and use that
as an indicator.
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
> drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
> 1 file changed, 30 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
> index c32fba550c8e0..1e78939625622 100644
> --- a/drivers/rtc/rtc-pm8xxx.c
> +++ b/drivers/rtc/rtc-pm8xxx.c
> @@ -61,6 +61,7 @@ struct pm8xxx_rtc {
> struct rtc_device *rtc;
> struct regmap *regmap;
> bool allow_set_time;
> + bool no_alarm;
How about inverting this one and naming it has_alarm or similar to avoid
the double negation in your conditionals (!no_alarm)?
> int alarm_irq;
> const struct pm8xxx_rtc_regs *regs;
> struct device *dev;
> @@ -473,9 +474,14 @@ 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;
> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
> + "qcom,no-alarm");
> +
Stray newline.
> + if (!rtc_dd->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");
> @@ -503,7 +509,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, rtc_dd);
>
> - device_init_wakeup(&pdev->dev, 1);
> + if (!rtc_dd->no_alarm)
> + device_init_wakeup(&pdev->dev, 1);
>
> rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
> if (IS_ERR(rtc_dd->rtc))
> @@ -512,27 +519,36 @@ 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->no_alarm) {
> + 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_rtc_register_device(rtc_dd->rtc);
> if (rc)
> return rc;
>
> - rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> - if (rc)
> - return rc;
> + if (!rtc_dd->no_alarm) {
> + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> + if (rc)
> + return rc;
> + } else {
> + clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
I assume that you should be clearing the feature bit before registering
the RTC.
> + }
>
> return 0;
> }
Johan
On 10/16/24 2:42 AM, Johan Hovold wrote:
> On Mon, Oct 14, 2024 at 08:47:26PM -0400, Jonathan Marek wrote:
>> 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.
>
> An alternative may be to drop the alarm interrupt from DT and use that
> as an indicator.
>
That wouldn't be right, the registers/interrupt still exist and should
be described in DT.
(if you have firmware that allows access to the alarm, now you only have
to delete the qcom,no-alarm property in your dts to use it)
>> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
>> ---
>> drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
>> 1 file changed, 30 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
>> index c32fba550c8e0..1e78939625622 100644
>> --- a/drivers/rtc/rtc-pm8xxx.c
>> +++ b/drivers/rtc/rtc-pm8xxx.c
>> @@ -61,6 +61,7 @@ struct pm8xxx_rtc {
>> struct rtc_device *rtc;
>> struct regmap *regmap;
>> bool allow_set_time;
>> + bool no_alarm;
>
> How about inverting this one and naming it has_alarm or similar to avoid
> the double negation in your conditionals (!no_alarm)?
>
My reasoning is that the DT flag has to be negative, and its better to
use the same name as the DT flag, but inverting it is OK.
>> int alarm_irq;
>> const struct pm8xxx_rtc_regs *regs;
>> struct device *dev;
>> @@ -473,9 +474,14 @@ 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;
>> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
>> + "qcom,no-alarm");
>> +
>
> Stray newline.
>
That's not a stray newline?
>> + if (!rtc_dd->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");
>> @@ -503,7 +509,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
>>
>> platform_set_drvdata(pdev, rtc_dd);
>>
>> - device_init_wakeup(&pdev->dev, 1);
>> + if (!rtc_dd->no_alarm)
>> + device_init_wakeup(&pdev->dev, 1);
>>
>> rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
>> if (IS_ERR(rtc_dd->rtc))
>> @@ -512,27 +519,36 @@ 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->no_alarm) {
>> + 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_rtc_register_device(rtc_dd->rtc);
>> if (rc)
>> return rc;
>>
>> - rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
>> - if (rc)
>> - return rc;
>> + if (!rtc_dd->no_alarm) {
>> + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
>> + if (rc)
>> + return rc;
>> + } else {
>> + clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
>
> I assume that you should be clearing the feature bit before registering
> the RTC.
>
Right, it just needs to be after devm_rtc_allocate_device, not
devm_rtc_register_device.
>> + }
>>
>> return 0;
>> }
>
> Johan
>
On Wed, Oct 16, 2024 at 08:44:26AM -0400, Jonathan Marek wrote:
> On 10/16/24 2:42 AM, Johan Hovold wrote:
> > On Mon, Oct 14, 2024 at 08:47:26PM -0400, Jonathan Marek wrote:
> >> 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.
> >
> > An alternative may be to drop the alarm interrupt from DT and use that
> > as an indicator.
>
> That wouldn't be right, the registers/interrupt still exist and should
> be described in DT.
Yeah, the registers are still there, and are probably readable too
(IIRC), but the OS will never receive any interrupts.
> (if you have firmware that allows access to the alarm, now you only have
> to delete the qcom,no-alarm property in your dts to use it)
Fair enough. And the new flag mirrors the old.
> >> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> >> ---
> >> drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
> >> 1 file changed, 30 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
> >> index c32fba550c8e0..1e78939625622 100644
> >> --- a/drivers/rtc/rtc-pm8xxx.c
> >> +++ b/drivers/rtc/rtc-pm8xxx.c
> >> @@ -61,6 +61,7 @@ struct pm8xxx_rtc {
> >> struct rtc_device *rtc;
> >> struct regmap *regmap;
> >> bool allow_set_time;
> >> + bool no_alarm;
> >
> > How about inverting this one and naming it has_alarm or similar to avoid
> > the double negation in your conditionals (!no_alarm)?
> >
>
> My reasoning is that the DT flag has to be negative, and its better to
> use the same name as the DT flag, but inverting it is OK.
I agree about the dt parameter, but I still I prefer a non-negated
variable (similar to allow_set_time).
> >> int alarm_irq;
> >> const struct pm8xxx_rtc_regs *regs;
> >> struct device *dev;
> >> @@ -473,9 +474,14 @@ 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;
> >> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
> >> + "qcom,no-alarm");
> >> +
> >
> > Stray newline.
> >
>
> That's not a stray newline?
There was no empty line between the assignment and check before this
change, but now there is even though there should not be.
> >> + if (!rtc_dd->no_alarm) {
> >> + rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
> >> + if (rtc_dd->alarm_irq < 0)
> >> + return -ENXIO;
> >> + }
Johan
On 10/16/24 9:02 AM, Johan Hovold wrote:
>>>> int alarm_irq;
>>>> const struct pm8xxx_rtc_regs *regs;
>>>> struct device *dev;
>>>> @@ -473,9 +474,14 @@ 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;
>>>> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
>>>> + "qcom,no-alarm");
>>>> +
>>>
>>> Stray newline.
>>>
>>
>> That's not a stray newline?
>
> There was no empty line between the assignment and check before this
> change, but now there is even though there should not be.
>
There was no empty line between the "alarm_irq" assignment and check,
and there still isn't. That empty line separating the new
of_property_read_bool() line.
I could move both of_property_read_bool() lines together to make it look
better.
>>>> + if (!rtc_dd->no_alarm) {
>>>> + rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
>>>> + if (rtc_dd->alarm_irq < 0)
>>>> + return -ENXIO;
>>>> + }
>
> Johan
>
On Wed, Oct 16, 2024 at 09:12:08AM -0400, Jonathan Marek wrote: > On 10/16/24 9:02 AM, Johan Hovold wrote: > >>>> int alarm_irq; > >>>> const struct pm8xxx_rtc_regs *regs; > >>>> struct device *dev; > >>>> @@ -473,9 +474,14 @@ 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; > >>>> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node, > >>>> + "qcom,no-alarm"); > >>>> + > >>> > >>> Stray newline. > >> > >> That's not a stray newline? > > > > There was no empty line between the assignment and check before this > > change, but now there is even though there should not be. > > There was no empty line between the "alarm_irq" assignment and check, > and there still isn't. That empty line separating the new > of_property_read_bool() line. Ah, sorry, my bad. > I could move both of_property_read_bool() lines together to make it look > better. Yeah, that sounds like a good idea. Johan
On 16/10/2024 08:42:46+0200, Johan Hovold wrote:
> On Mon, Oct 14, 2024 at 08:47:26PM -0400, Jonathan Marek wrote:
> > 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.
>
> An alternative may be to drop the alarm interrupt from DT and use that
> as an indicator.
>
> > Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> > ---
> > drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
> > 1 file changed, 30 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
> > index c32fba550c8e0..1e78939625622 100644
> > --- a/drivers/rtc/rtc-pm8xxx.c
> > +++ b/drivers/rtc/rtc-pm8xxx.c
> > @@ -61,6 +61,7 @@ struct pm8xxx_rtc {
> > struct rtc_device *rtc;
> > struct regmap *regmap;
> > bool allow_set_time;
> > + bool no_alarm;
>
> How about inverting this one and naming it has_alarm or similar to avoid
> the double negation in your conditionals (!no_alarm)?
>
> > int alarm_irq;
> > const struct pm8xxx_rtc_regs *regs;
> > struct device *dev;
> > @@ -473,9 +474,14 @@ 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;
> > + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
> > + "qcom,no-alarm");
> > +
>
> Stray newline.
>
> > + if (!rtc_dd->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");
> > @@ -503,7 +509,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
> >
> > platform_set_drvdata(pdev, rtc_dd);
> >
> > - device_init_wakeup(&pdev->dev, 1);
> > + if (!rtc_dd->no_alarm)
> > + device_init_wakeup(&pdev->dev, 1);
> >
> > rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
> > if (IS_ERR(rtc_dd->rtc))
> > @@ -512,27 +519,36 @@ 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->no_alarm) {
> > + 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_rtc_register_device(rtc_dd->rtc);
> > if (rc)
> > return rc;
> >
> > - rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> > - if (rc)
> > - return rc;
> > + if (!rtc_dd->no_alarm) {
> > + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> > + if (rc)
> > + return rc;
Also, probe must not fail after devm_rtc_allocate_device has been
called.so you could fix this with this patch.
> > + } else {
> > + clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
>
> I assume that you should be clearing the feature bit before registering
> the RTC.
>
> > + }
> >
> > return 0;
> > }
>
> Johan
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Mon, Oct 14, 2024 at 08:47:26PM -0400, Jonathan Marek wrote:
> 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.
>
Reviewed-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
Alexandre, please pick up the driver and dt-binding patch (i.e. patch 1
& 2) through your tree, and I can pick the dts patches through the qcom
tree.
Regards,
Bjorn
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
> drivers/rtc/rtc-pm8xxx.c | 44 +++++++++++++++++++++++++++-------------
> 1 file changed, 30 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
> index c32fba550c8e0..1e78939625622 100644
> --- a/drivers/rtc/rtc-pm8xxx.c
> +++ b/drivers/rtc/rtc-pm8xxx.c
> @@ -61,6 +61,7 @@ struct pm8xxx_rtc {
> struct rtc_device *rtc;
> struct regmap *regmap;
> bool allow_set_time;
> + bool no_alarm;
> int alarm_irq;
> const struct pm8xxx_rtc_regs *regs;
> struct device *dev;
> @@ -473,9 +474,14 @@ 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;
> + rtc_dd->no_alarm = of_property_read_bool(pdev->dev.of_node,
> + "qcom,no-alarm");
> +
> + if (!rtc_dd->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");
> @@ -503,7 +509,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, rtc_dd);
>
> - device_init_wakeup(&pdev->dev, 1);
> + if (!rtc_dd->no_alarm)
> + device_init_wakeup(&pdev->dev, 1);
>
> rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
> if (IS_ERR(rtc_dd->rtc))
> @@ -512,27 +519,36 @@ 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->no_alarm) {
> + 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_rtc_register_device(rtc_dd->rtc);
> if (rc)
> return rc;
>
> - rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> - if (rc)
> - return rc;
> + if (!rtc_dd->no_alarm) {
> + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
> + if (rc)
> + return rc;
> + } else {
> + clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
> + }
>
> return 0;
> }
>
> static void pm8xxx_remove(struct platform_device *pdev)
> {
> - dev_pm_clear_wake_irq(&pdev->dev);
> + struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev);
> +
> + if (!rtc_dd->no_alarm)
> + dev_pm_clear_wake_irq(&pdev->dev);
> }
>
> static struct platform_driver pm8xxx_rtc_driver = {
> --
> 2.45.1
>
© 2016 - 2026 Red Hat, Inc.