Hello, On 13/10/2026 15:16:50+0200, Imre Kaloz wrote: > The M48T35 of SGI IP35-family machines counts its year from 1968. Take > the epoch from a platform id table, "rtc-m48t35" for IP27 and > "rtc-m48t35-ip35" for IP35, and bound the year to the part's century: on > IP27 a year past 2069 now fails to set. > > Signed-off-by: Imre Kaloz > --- > drivers/rtc/rtc-m48t35.c | 33 +++++++++++++++++++-------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c > index 92f19bf997b2..fa228a2bb527 100644 > --- a/drivers/rtc/rtc-m48t35.c > +++ b/drivers/rtc/rtc-m48t35.c > @@ -49,6 +49,7 @@ struct m48t35_priv { > struct m48t35_rtc __iomem *reg; > size_t size; > unsigned long baseaddr; > + unsigned int epoch; > spinlock_t lock; > }; > > @@ -86,10 +87,7 @@ static int m48t35_read_time(struct device *dev, struct rtc_time *tm) > * Account for differences between how the RTC uses the values > * and how they are defined in a struct rtc_time; > */ > - tm->tm_year += 70; > - if (tm->tm_year <= 69) > - tm->tm_year += 100; > - > + tm->tm_year += priv->epoch - 1900; > tm->tm_mon--; > return 0; > } > @@ -108,18 +106,10 @@ static int m48t35_set_time(struct device *dev, struct rtc_time *tm) > min = tm->tm_min; > sec = tm->tm_sec; > > - if (yrs < 1970) > - return -EINVAL; > - > - yrs -= 1970; > - if (yrs > 255) /* They are unsigned */ > - return -EINVAL; > - > - if (yrs > 169) > + if (yrs < priv->epoch || yrs >= priv->epoch + 100) > return -EINVAL; > > - if (yrs >= 100) > - yrs -= 100; > + yrs -= priv->epoch; > Instead of open coding, you should use start_secs after setting the rtc range in probe(). attached i a patch I refreshed for the devm_rtc_allocate_device/devm_rtc_register_device conversion that you can include in this series. drivers/rtc/rtc-mt6397.c is an example that should be working for you. I never sent the patch because it is not clear from the datasheet how well leap year calculation works. My guess is that it worked in 2000 but fails in 2100. > sec = bin2bcd(sec); > min = bin2bcd(min); > @@ -149,9 +139,13 @@ static const struct rtc_class_ops m48t35_ops = { > > static int m48t35_probe(struct platform_device *pdev) > { > + const struct platform_device_id *id = platform_get_device_id(pdev); > struct resource *res; > struct m48t35_priv *priv; > > + if (!id) > + return -ENODEV; > + > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > if (!res) > return -ENODEV; > @@ -164,6 +158,7 @@ static int m48t35_probe(struct platform_device *pdev) > pdev->name)) > return -EBUSY; > > + priv->epoch = id->driver_data; > priv->baseaddr = res->start; > priv->reg = devm_ioremap(&pdev->dev, priv->baseaddr, priv->size); > if (!priv->reg) > @@ -178,11 +173,20 @@ static int m48t35_probe(struct platform_device *pdev) > return PTR_ERR_OR_ZERO(priv->rtc); > } > > +/* The year register on SGI IP35-family machines counts from 1968. */ > +static const struct platform_device_id m48t35_id_table[] = { > + { "rtc-m48t35", 1970 }, > + { "rtc-m48t35-ip35", 1968 }, > + { } > +}; > +MODULE_DEVICE_TABLE(platform, m48t35_id_table); > + > static struct platform_driver m48t35_platform_driver = { > .driver = { > .name = "rtc-m48t35", > }, > .probe = m48t35_probe, > + .id_table = m48t35_id_table, > }; > > module_platform_driver(m48t35_platform_driver); > @@ -191,3 +195,4 @@ MODULE_AUTHOR("Thomas Bogendoerfer "); > MODULE_DESCRIPTION("M48T35 RTC driver"); > MODULE_LICENSE("GPL"); > MODULE_ALIAS("platform:rtc-m48t35"); > +MODULE_ALIAS("platform:rtc-m48t35-ip35"); > -- > 2.47.3 > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com