[PATCH v3 4/7] rtc: spacemit: support the SpacemiT P1 RTC
Mateusz Jończyk
mat.jonczyk at o2.pl
Mon Jun 23 11:54:34 PDT 2025
W dniu 22.06.2025 o 05:29, Alex Elder pisze:
> Add support for the RTC found in the SpacemiT P1 PMIC. Initially
> only setting and reading the time are supported.
>
> The PMIC is implemented as a multi-function device. This RTC is
> probed based on this driver being named in a MFD cell in the simple
> MFD I2C driver.
>
> Signed-off-by: Alex Elder <elder at riscstar.com>
> ---
> v3: - Added this driver to the series, in response to Lee Jones saying
> more than one MFD sub-device was required to be acceptable
[snip]
> +static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
> +{
> + struct p1_rtc *p1 = dev_get_drvdata(dev);
> + u8 time[tu_count];
> + int ret;
> +
> + ret = regmap_bulk_read(p1->regmap, RTC_COUNT_BASE, &time, sizeof(time));
> + if (ret)
> + return ret;
Hello,
Are you sure that you read the time parts consistently here? I mean:
is there a risk that the clock is updating below you - so that for
example during the transition
12:59:59 -> 13:00:00
you are going to read 12:00:00 or 12:59:00?
If so, you could for example read the time in a loop until you get
two same readouts.
> +
> + t->tm_sec = time[tu_second] & GENMASK(5, 0);
> + t->tm_min = time[tu_minute] & GENMASK(5, 0);
> + t->tm_hour = time[tu_hour] & GENMASK(4, 0);
> + t->tm_mday = (time[tu_day] & GENMASK(4, 0)) + 1;
> + t->tm_mon = time[tu_month] & GENMASK(3, 0);
> + t->tm_year = (time[tu_year] & GENMASK(5, 0)) + 100;
Is it necessary to use the bitmasks here? Are the higher bits undefined
in hardware? If so, is it necessary to mask them while writing the time
in p1_rtc_set_time()?
> + /* tm_wday, tm_yday, and tm_isdst aren't used */
> +
> + return 0;
> +}
> +
> +static int p1_rtc_set_time(struct device *dev, struct rtc_time *t)
> +{
> + struct p1_rtc *p1 = dev_get_drvdata(dev);
> + u8 time[tu_count];
> + int ret;
> +
> + time[tu_second] = t->tm_sec;
> + time[tu_minute] = t->tm_min;
> + time[tu_hour] = t->tm_hour;
> + time[tu_day] = t->tm_mday - 1;
> + time[tu_month] = t->tm_mon;
> + time[tu_year] = t->tm_year - 100;
> +
> + /* Disable the RTC to update; re-enable again when done */
> + ret = regmap_update_bits(p1->regmap, RTC_CTRL, RTC_EN, 0);
> + if (ret)
> + return ret;
> +
> + ret = regmap_bulk_write(p1->regmap, RTC_COUNT_BASE, time, sizeof(time));
> +
> + (void)regmap_update_bits(p1->regmap, RTC_CTRL, RTC_EN, RTC_EN);
Perhaps you shouldn't ignore any errors here - failing to restart
the clock should make p1_rtc_set_time() return an error code.
> +
> + return ret;
> +}
> +
Greetings,
Mateusz
More information about the linux-riscv
mailing list