Hello Jonathan, On Thu, Sep 24, 2020 at 09:24:53PM +0200, Jonathan Neuschäfer wrote: > +#define NTXEC_REG_WRITE_YEAR 0x10 > +#define NTXEC_REG_WRITE_MONTH 0x11 > +#define NTXEC_REG_WRITE_DAY 0x12 > +#define NTXEC_REG_WRITE_HOUR 0x13 > +#define NTXEC_REG_WRITE_MINUTE 0x14 > +#define NTXEC_REG_WRITE_SECOND 0x15 > + > +#define NTXEC_REG_READ_YM 0x20 > +#define NTXEC_REG_READ_DH 0x21 > +#define NTXEC_REG_READ_MS 0x23 Is this an official naming? I think at least ..._MS is a poor name. Maybe consider ..._MINSEC instead and make the other two names a bit longer for consistency? > +static int ntxec_read_time(struct device *dev, struct rtc_time *tm) > +{ > + struct ntxec_rtc *rtc = dev_get_drvdata(dev); > + unsigned int value; > + int res; > + > + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_YM, &value); > + if (res < 0) > + return res; > + > + tm->tm_year = (value >> 8) + 100; > + tm->tm_mon = (value & 0xff) - 1; > + > + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_DH, &value); > + if (res < 0) > + return res; > + > + tm->tm_mday = value >> 8; > + tm->tm_hour = value & 0xff; > + > + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_MS, &value); > + if (res < 0) > + return res; > + > + tm->tm_min = value >> 8; > + tm->tm_sec = value & 0xff; > + > + return 0; > +} > + > +static int ntxec_set_time(struct device *dev, struct rtc_time *tm) > +{ > + struct ntxec_rtc *rtc = dev_get_drvdata(dev); > + int res = 0; > + > + res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_YEAR, ntxec_reg8(tm->tm_year - 100)); > + if (res) > + return res; > + > + res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_MONTH, ntxec_reg8(tm->tm_mon + 1)); > + if (res) > + return res; > + > + res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_DAY, ntxec_reg8(tm->tm_mday)); > + if (res) > + return res; > + > + res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_HOUR, ntxec_reg8(tm->tm_hour)); > + if (res) > + return res; > + > + res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_MINUTE, ntxec_reg8(tm->tm_min)); > + if (res) > + return res; > + > + return regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_SECOND, ntxec_reg8(tm->tm_sec)); I wonder: Is this racy? If you write minute, does the seconds reset to zero or something like that? Or can it happen, that after writing the minute register and before writing the second register the seconds overflow and you end up with the time set to a minute later than intended? If so it might be worth to set the seconds to 0 at the start of the function (with an explaining comment). .read_time has a similar race. What happens if minutes overflow between reading NTXEC_REG_READ_DH and NTXEC_REG_READ_MS? > +static struct platform_driver ntxec_rtc_driver = { > + .driver = { > + .name = "ntxec-rtc", > + }, > + .probe = ntxec_rtc_probe, No .remove function? > +}; > +module_platform_driver(ntxec_rtc_driver); > + > +MODULE_AUTHOR("Jonathan Neuschäfer "); > +MODULE_DESCRIPTION("RTC driver for Netronix EC"); > +MODULE_LICENSE("GPL"); Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |