From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: Markus Probst <markus.probst@posteo.de>
Cc: "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Uwe Kleine-König" <uwe@kleine-koenig.org>,
"Andrew Lunn" <andrew@lunn.ch>,
"Gregory Clement" <gregory.clement@bootlin.com>,
"Sebastian Hesselbarth" <sebastian.hesselbarth@gmail.com>,
"Michael Langer" <michael.brainbug.langer@googlemail.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Linus Walleij" <linusw@kernel.org>,
linux-arm-kernel@lists.infradead.org, linux-rtc@vger.kernel.org,
devicetree@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 4/6] rtc: s35390a: force 24-hour mode
Date: Thu, 20 Aug 2026 17:25:56 +0200 [thread overview]
Message-ID: <20260820152556c6da4fce@mail.local> (raw)
In-Reply-To: <20260819232634fd70f621@mail.local>
On 20/08/2026 01:26:34+0200, Alexandre Belloni wrote:
> On 19/08/2026 22:57:13+0000, Markus Probst wrote:
> > On Thu, 2026-08-20 at 00:20 +0200, Alexandre Belloni wrote:
> > > On 19/08/2026 22:05:56+0000, Markus Probst wrote:
> > > > Instead of trying to remember the current 12/24-hour mode, which could
> > > > result in time corruption if out of sync, we force the use of the 24-hour
> > > > mode. Set to 24-hour mode if in 12-hour mode on startup and assume
> > > > 24-hour mode. The 24-hour mode is already forced on reset.
> > > >
> > > > Signed-off-by: Markus Probst <markus.probst@posteo.de>
> > > > ---
> > > > drivers/rtc/rtc-s35390a.c | 67 +++++++++++++++++++++--------------------------
> > > > 1 file changed, 30 insertions(+), 37 deletions(-)
> > > >
> > > > diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
> > > > index 575bb256eb25..b34a3f7e8476 100644
> > > > --- a/drivers/rtc/rtc-s35390a.c
> > > > +++ b/drivers/rtc/rtc-s35390a.c
> > > > @@ -64,7 +64,6 @@ MODULE_DEVICE_TABLE(of, s35390a_of_match);
> > > >
> > > > struct s35390a {
> > > > struct i2c_client *client[8];
> > > > - int twentyfourhour;
> > > > };
> > > >
> > > > static int s35390a_set_reg(struct s35390a *s35390a, int reg, u8 *buf, int len)
> > > > @@ -181,31 +180,6 @@ static int s35390a_disable_test_mode(struct s35390a *s35390a)
> > > > return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
> > > > }
> > > >
> > > > -static char s35390a_hr2reg(struct s35390a *s35390a, int hour)
> > > > -{
> > > > - if (s35390a->twentyfourhour)
> > > > - return bin2bcd(hour);
> > > > -
> > > > - if (hour < 12)
> > > > - return bin2bcd(hour);
> > > > -
> > > > - return 0x40 | bin2bcd(hour - 12);
> > > > -}
> > > > -
> > > > -static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
> > > > -{
> > > > - unsigned hour;
> > > > -
> > > > - if (s35390a->twentyfourhour)
> > > > - return bcd2bin(reg & 0x3f);
> > > > -
> > > > - hour = bcd2bin(reg & 0x3f);
> > > > - if (reg & 0x40)
> > > > - hour += 12;
> > > > -
> > > > - return hour;
> > > > -}
> > > > -
> > > > static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
> > > > {
> > > > struct i2c_client *client = to_i2c_client(dev);
> > > > @@ -225,7 +199,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
> > > > buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1);
> > > > buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday);
> > > > buf[S35390A_BYTE_WDAY] = bin2bcd(tm->tm_wday);
> > > > - buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour);
> > > > + buf[S35390A_BYTE_HOURS] = bin2bcd(tm->tm_hour);
> > > > buf[S35390A_BYTE_MINS] = bin2bcd(tm->tm_min);
> > > > buf[S35390A_BYTE_SECS] = bin2bcd(tm->tm_sec);
> > > >
> > > > @@ -256,7 +230,7 @@ static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > > >
> > > > tm->tm_sec = bcd2bin(buf[S35390A_BYTE_SECS]);
> > > > tm->tm_min = bcd2bin(buf[S35390A_BYTE_MINS]);
> > > > - tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]);
> > > > + tm->tm_hour = bcd2bin(buf[S35390A_BYTE_HOURS] & 0x3f);
> > > > tm->tm_wday = bcd2bin(buf[S35390A_BYTE_WDAY]);
> > > > tm->tm_mday = bcd2bin(buf[S35390A_BYTE_DAY]);
> > > > tm->tm_mon = bcd2bin(buf[S35390A_BYTE_MONTH]) - 1;
> > > > @@ -325,8 +299,7 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> > > > else
> > > > buf[S35390A_ALRM_BYTE_WDAY] = 0;
> > > >
> > > > - buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
> > > > - alm->time.tm_hour) | 0x80;
> > > > + buf[S35390A_ALRM_BYTE_HOURS] = bin2bcd(alm->time.tm_hour) | 0x80;
> > > > buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80;
> > > >
> > > > if (alm->time.tm_hour >= 12)
> > > > @@ -381,8 +354,7 @@ static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
> > > >
> > > > if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80)
> > > > alm->time.tm_hour =
> > > > - s35390a_reg2hr(s35390a,
> > > > - buf[S35390A_ALRM_BYTE_HOURS] & ~0x80);
> > > > + bcd2bin(buf[S35390A_ALRM_BYTE_HOURS] & 0x3f);
> > > >
> > > > if (buf[S35390A_ALRM_BYTE_MINS] & 0x80)
> > > > alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80);
> > > > @@ -459,7 +431,7 @@ static int s35390a_probe(struct i2c_client *client)
> > > > unsigned int i;
> > > > struct s35390a *s35390a;
> > > > struct rtc_device *rtc;
> > > > - u8 buf, status1;
> > > > + u8 buf, status1, time[7];
> > > > struct device *dev = &client->dev;
> > > > struct nvmem_config nvmem_cfg = {
> > > > .name = "s35390a_nvram",
> > > > @@ -503,10 +475,31 @@ static int s35390a_probe(struct i2c_client *client)
> > > > return err_read;
> > > > }
> > > >
> > > > - if (status1 & S35390A_FLAG_24H)
> > > > - s35390a->twentyfourhour = 1;
> > > > - else
> > > > - s35390a->twentyfourhour = 0;
> > > > + if (!(status1 & S35390A_FLAG_24H) && err_read != 1) {
> > > > + unsigned int hour;
> > > > +
> > > > + status1 |= S35390A_FLAG_24H;
> > > > +
> > > > + err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, time, sizeof(time));
> > > > + if (err < 0)
> > > > + return dev_err_probe(dev, err, "reading 12-hour time failed\n");
> > > > +
> > > > + /* converting to 24-hour time */
> > > > + time[S35390A_BYTE_HOURS] = bitrev8(time[S35390A_BYTE_HOURS]);
> > > > + hour = bcd2bin(time[S35390A_BYTE_HOURS] & 0x3f);
> > > > + if (time[S35390A_BYTE_HOURS] & 0x40)
> > > > + hour += 12;
> > > > +
> > > > + time[S35390A_BYTE_HOURS] = bitrev8(bin2bcd(hour));
> > > > +
> > > > + err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &status1, sizeof(status1));
> > > > + if (err < 0)
> > > > + return dev_err_probe(dev, err, "setting 24-hour mode failed\n");
> > > > +
> > > > + err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, time, sizeof(time));
> > > > + if (err < 0)
> > > > + return dev_err_probe(dev, err, "setting 24-hour time failed\n");
> > >
> > > No, don't do this, this will break existing users as your conversion may
> > > happen after a minute rollover. The only function in which you are
> > > allowed to change the time registers is set_time. You definitively need
> > > to be able to read 12H mode time but you are allowed to only support
> > > writing 24h time.
> > >
> > > Also, this is super verbose, adding strings to the kernel makes it
> > > bloated.
> > >
> > > To avoid any desync, simply test for the S35390A_FLAG_24H bit in status
> > > in s35390a_rtc_read_time as the register is already read anyway.
> > >
> > I think that would defeat the whole point of the patch, that the rtc is
> > always in 24-hour mode. If this driver was always used with the rtc, it
> > already should be in 24-hour mode, as thats the mode this driver does
> > initialize the rtc.
>
> This assumption may not be true, the RTC may have been initialized by a
> bootloader or a different system in the factory.
>
> > Your idea would work for the time, but not in combination with alarms.
> > If the rtc could be in 12-hour mode, then this would need to be
> > considered in setting and reading alarm. Also setting 24-hour mode
> > inside set_time would then also require to convert the alarm time.
> > Effectively making it less maintainable than before.
>
> Note that while setting the time when an alarm has been set is not
> forbidden, it is never guaranteed to work anyway. I guess something we
> could do in the core is that whenever the time is set we go over the
> timerqueue and set the alarm again.
Actually this is already what we do so this is not an issue.
>This would allow to remove the UIE
> disabling/enabling dance.
>
> >
> > Currently s35390a_init does initialize the rtc in 24-hour mode, while
> > not updating s35390a->twentyfourhour. So some change needs to be made.
> > Just setting s35390a->twentyfourhour inside s35390a_init might now be
> > the simplest solution here.
>
> Or maybe simply stop caching the value.
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2026-08-20 15:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-19 22:05 [PATCH v5 0/6] rtc: s35390a: Allow use of output pin for interrupt signal 1 for wakealarm Markus Probst
2026-08-19 22:05 ` [PATCH v5 1/6] dt-bindings: rtc: Add pinctrl for S35390A Markus Probst
2026-08-19 22:05 ` [PATCH v5 2/6] rtc: s35390a: Add missing newline to dev_err Markus Probst
2026-08-19 22:05 ` [PATCH v5 3/6] rtc: s35390a: Fix alarm not disabling Markus Probst
2026-08-19 22:25 ` Alexandre Belloni
2026-08-19 22:29 ` Markus Probst
2026-08-19 22:05 ` [PATCH v5 4/6] rtc: s35390a: force 24-hour mode Markus Probst
2026-08-19 22:20 ` Alexandre Belloni
2026-08-19 22:57 ` Markus Probst
2026-08-19 23:26 ` Alexandre Belloni
2026-08-20 15:25 ` Alexandre Belloni [this message]
2026-08-19 22:05 ` [PATCH v5 5/6] rtc: s35390a: Add pinctrl Markus Probst
2026-08-19 22:05 ` [PATCH v5 6/6] rtc: s35390a: Add synology quirk Markus Probst
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=20260820152556c6da4fce@mail.local \
--to=alexandre.belloni@bootlin.com \
--cc=akpm@linux-foundation.org \
--cc=andrew@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregory.clement@bootlin.com \
--cc=krzk+dt@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=markus.probst@posteo.de \
--cc=michael.brainbug.langer@googlemail.com \
--cc=robh@kernel.org \
--cc=sebastian.hesselbarth@gmail.com \
--cc=uwe@kleine-koenig.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