[PATCH v4 5/7] rtc: New driver for RTC in Netronix embedded controller

Alexandre Belloni alexandre.belloni at bootlin.com
Sun Nov 22 18:10:54 EST 2020


Hi,

On 22/11/2020 23:27:37+0100, Jonathan Neuschäfer wrote:
> With this driver, mainline Linux can keep its time and date in sync with
> the vendor kernel.
> 
> Advanced functionality like alarm and automatic power-on is not yet
> supported.
> 
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Acked-by: Alexandre Belloni <alexandre.belloni at bootlin.com>

However, two comments below:

> +static int ntxec_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct ntxec_rtc *rtc = dev_get_drvdata(dev);
> +	int res = 0;
> +
> +	/*
> +	 * To avoid time overflows while we're writing the full date/time,
> +	 * set the seconds field to zero before doing anything else. For the
> +	 * next 59 seconds (plus however long it takes until the RTC's next
> +	 * update of the second field), the seconds field will not overflow
> +	 * into the other fields.
> +	 */
> +	res = regmap_write(rtc->ec->regmap, NTXEC_REG_WRITE_SECOND, ntxec_reg8(0));
> +	if (res)
> +		return res;
> +
> +	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));

Couldn't you do a regmap_block_write or a regmap_multi_reg_write which
would be more efficient as they would be locking the regmap only once.

> +}
> +
> +static const struct rtc_class_ops ntxec_rtc_ops = {
> +	.read_time = ntxec_read_time,
> +	.set_time = ntxec_set_time,
> +};
> +
> +static int ntxec_rtc_probe(struct platform_device *pdev)
> +{
> +	struct rtc_device *dev;
> +	struct ntxec_rtc *rtc;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc)
> +		return -ENOMEM;
> +
> +	rtc->dev = &pdev->dev;
> +	rtc->ec = dev_get_drvdata(pdev->dev.parent);
> +	platform_set_drvdata(pdev, rtc);
> +
> +	dev = devm_rtc_allocate_device(&pdev->dev);
> +	if (IS_ERR(dev))
> +		return PTR_ERR(dev);
> +
> +	dev->ops = &ntxec_rtc_ops;
> +	dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
> +	dev->range_max = 9025257599LL; /* 2255-12-31 23:59:59 */
> +
> +	return rtc_register_device(dev);

Note that this won't compile after
https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git/commit/?id=fdcfd854333be5b30377dc5daa9cd0fa1643a979

We can solve that with immutable branches though.

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



More information about the linux-arm-kernel mailing list