From: "Arnd Bergmann" <arnd@arndb.de>
To: "Ciprian Costea" <ciprianmarian.costea@oss.nxp.com>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Will Deacon" <will@kernel.org>
Cc: linux-rtc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
"NXP S32 Linux Team" <s32@nxp.com>,
imx@lists.linux.dev, "Christophe Lizzi" <clizzi@redhat.com>,
"Alberto Ruiz" <aruizrui@redhat.com>,
"Enric Balletbo" <eballetb@redhat.com>,
"Bogdan Hamciuc" <bogdan.hamciuc@nxp.com>,
"Ghennadi Procopciuc" <Ghennadi.Procopciuc@nxp.com>
Subject: Re: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
Date: Fri, 06 Dec 2024 13:41:55 +0100 [thread overview]
Message-ID: <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com> (raw)
In-Reply-To: <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
On Fri, Dec 6, 2024, at 13:05, Ciprian Marian Costea wrote:
> On 12/6/2024 10:04 AM, Arnd Bergmann wrote:
>>
>> However, the range of the register value is only 32 bits,
>> which means there is no need to ever divide it by a 64-bit
>> number, and with the 32kHz clock in the binding example,
>> you only have about 37 hours worth of range here.
>>
>
> I am not sure what is the suggestion here. To cast 'cycles' variable to
> 32-bit ?
> If yes, indeed 'div_u64' converts 'cycles' (the divisor) to 32-bit so I
> agree it should be u32 instead of u64.
> If not, I would prefer to keep using a 64-by-32 division and avoid
> casting 'hz' to 32-bit.
The confusing bit here is that the extra function just serves to
the dividend 'cycles' from 32-bit to 64-bit, and then calling
div_u64() implicitly casts the dividend 'hz' from 64-bit to
32-bit, so you definitely get a 32-by-32 division already
if the function is inlined properly.
I think storing 'rtc_hz' as a u32 variable and adding a range
check when filling it would help, mainly to save the next reader
from having to understand what is going on.
>> It would appear that this makes the rtc unsuitable for
>> storing absolute time across reboots, and only serve during
>> runtime, which is a limitation you should probably document.
>>
>
> Actually there is the option to use DIV512 and/or DIV32 hardware
> divisors for the RTC clock. The driver uses a DIV512 divisor by default
> in order to achieve higher RTC count ranges (by achieving a smaller RTC
> freq). Therefore, the 37 hours become 37 * 512 => ~ 2 years.
Ah, makes sense. Can you add comments in an appropriate place in
the code about this?
> However, the rtc limitation of not being persistent during reboot
> remains, due to hardware RTC module registers present of NXP S32G2/S32G3
> SoCs being reset during system reboot. On the other hand, during system
> suspend, the RTC module will keep counting if a clock source is available.
>
> Currently, this limittion is documented as follows:
> "RTC tracks clock time during system suspend. It can be a wakeup source
> for the S32G2/S32G3 SoC based boards.
>
> The RTC module from S32G2/S32G3 is not battery-powered and it is not
> kept alive during system reset."
My bad, I really should not have skipped the patch
description ;-)
>> If 'counter' wraps every 37 hours, this will inevitably fail,
>> right? E.g. if priv->base.cycles was already at a large
>> 32-bit number, even reading it shortly later will produce
>> a small value after the wraparound.
>>
>> Using something like time_before() should address this,
>> but I think you may need a custom version that works on
>> 32-bit numbers.
>>
>
> This is correct. Would the following change be acceptable ?
>
> - if (counter < priv->base.cycles)
> - return -EINVAL;
> -
> - counter -= priv->base.cycles;
> + if (counter < priv->base.cycles) {
> + /* A rollover on RTCCTN has occurred */
> + counter += RTCCNT_MAX_VAL - priv->base.cycles;
> + priv->base.cycles = 0;
> + } else {
> + counter -= priv->base.cycles;
> + }
This is the same as just removing the error handling and
relying on unsigned integer overflow semantics.
The usual check we do in time_before()/time_after instead
checks if the elapsed time is less than half the available
range:
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)((b) - (a)) < 0))
>>> +static int s32g_rtc_resume(struct device *dev)
>>> +{
>>> + struct rtc_priv *priv = dev_get_drvdata(dev);
>>> + int ret;
>>> +
>>> + if (!device_may_wakeup(dev))
>>> + return 0;
>>> +
>>> + /* Disable wake-up interrupts */
>>> + s32g_enable_api_irq(dev, 0);
>>> +
>>> + ret = rtc_clk_src_setup(priv);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /*
>>> + * Now RTCCNT has just been reset, and is out of sync with priv->base;
>>> + * reapply the saved time settings.
>>> + */
>>> + return s32g_rtc_set_time(dev, &priv->base.tm);
>>> +}
>>
>> This also fails if the system has been suspended for more than
>> 37 hours, right?
>
> Actually, the system would not go into suspend (returning with error) if
> the alarm setting passes the 32-bit / clk_freq range.
> The check is added in 'sec_to_rtcval' which is called from the suspend
> routine.
Who sets that alarm though? Are you relying on custom userspace
for this, or is that something that the kernel already does
that I'm missing?
Arnd
next prev parent reply other threads:[~2024-12-06 12:42 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-06 7:09 [PATCH v6 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea
2024-12-06 7:09 ` [PATCH v6 1/4] dt-bindings: rtc: add schema for NXP " Ciprian Costea
2024-12-10 23:04 ` Rob Herring (Arm)
2024-12-06 7:09 ` [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea
2024-12-06 8:04 ` Arnd Bergmann
2024-12-06 12:05 ` Ciprian Marian Costea
2024-12-06 12:41 ` Arnd Bergmann [this message]
2024-12-09 17:17 ` Ciprian Marian Costea
2024-12-10 8:22 ` Arnd Bergmann
2024-12-10 23:07 ` Alexandre Belloni
2024-12-10 5:22 ` kernel test robot
2024-12-10 23:25 ` Alexandre Belloni
2025-02-06 10:36 ` Ciprian Marian Costea
2024-12-06 7:09 ` [PATCH v6 3/4] arm64: defconfig: add S32G RTC module support Ciprian Costea
2024-12-06 7:09 ` [PATCH v6 4/4] MAINTAINERS: add NXP S32G RTC driver Ciprian Costea
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com \
--to=arnd@arndb.de \
--cc=Ghennadi.Procopciuc@nxp.com \
--cc=alexandre.belloni@bootlin.com \
--cc=aruizrui@redhat.com \
--cc=bogdan.hamciuc@nxp.com \
--cc=catalin.marinas@arm.com \
--cc=ciprianmarian.costea@oss.nxp.com \
--cc=clizzi@redhat.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=eballetb@redhat.com \
--cc=imx@lists.linux.dev \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=robh@kernel.org \
--cc=s32@nxp.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox