All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: linux-aspeed@lists.ozlabs.org
Subject: [PATCH 1/2] rtc: Add ASPEED RTC driver
Date: Thu, 4 Oct 2018 20:37:00 +0200	[thread overview]
Message-ID: <20181004183700.GA5626@piout.net> (raw)
In-Reply-To: <20181003133155.27494-2-joel@jms.id.au>

Hello,

On 03/10/2018 15:31:54+0200, Joel Stanley wrote:
> +static int aspeed_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct aspeed_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int cent, year, mon, day, hour, min, sec;
> +	unsigned long flags;
> +	u32 reg1, reg2;
> +
> +	spin_lock_irqsave(&rtc->lock, flags);
> +
> +	do {
> +		reg2 = readl(rtc->base + RTC_YEAR);
> +		reg1 = readl(rtc->base + RTC_TIME);
> +	} while (reg2 != readl(rtc->base + RTC_YEAR));
> +
> +	day  = (reg1 >> 24) & 0x1f;
> +	hour = (reg1 >> 16) & 0x1f;
> +	min  = (reg1 >>  8) & 0x3f;
> +	sec  = (reg1 >>  0) & 0x3f;
> +	cent = (reg2 >> 16) & 0x1f;
> +	year = (reg2 >>  8) & 0x7f;
> +	/*
> +	 * Month is 1-12 in hardware, and 0-11 in struct rtc_time, however we
> +	 * are using mktime64 which is 1-12, so no adjustment is necessary
> +	 */
> +	mon  = (reg2 >>  0) & 0x0f;
> +
> +	rtc_time64_to_tm(mktime64(cent * 100 + year, mon, day, hour, min, sec),
> +			tm);
> +

This is quite wasteful. You already have the broken out time. Why don't
you directly fill the tm struct?

> +static int aspeed_rtc_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	struct aspeed_rtc *rtc;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	rtc->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(rtc->base))
> +		return PTR_ERR(rtc->base);
> +
> +	platform_set_drvdata(pdev, rtc);
> +
> +	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> +						&aspeed_rtc_ops, THIS_MODULE);
> +

Please use devm_rtc_allocate_device to allocate the rtc and then
register it with rtc_register_device. Please also fill
rtc->range_{min,max} before the registration.

> +	if (IS_ERR(rtc->rtc_dev))
> +		return PTR_ERR(rtc->rtc_dev);
> +
> +	spin_lock_init(&rtc->lock);
> +
> +	/* Enable RTC and clear the unlock bit */
> +	writel(RTC_ENABLE, rtc->base + RTC_CTRL);
> +

Maybe this should only be done in set_time so you can know whether the
time that is read in read_time has a chance to be valid.

For example you could return -EINVAL when RTC_ENABLE is not set if this
bit is readable.

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

WARNING: multiple messages have this Message-ID (diff)
From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: Joel Stanley <joel@jms.id.au>
Cc: Alessandro Zummo <a.zummo@towertech.it>,
	linux-rtc@vger.kernel.org, Andrew Jeffery <andrew@aj.id.au>,
	Christian Svensson <christian@cmd.nu>,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org
Subject: Re: [PATCH 1/2] rtc: Add ASPEED RTC driver
Date: Thu, 4 Oct 2018 20:37:00 +0200	[thread overview]
Message-ID: <20181004183700.GA5626@piout.net> (raw)
In-Reply-To: <20181003133155.27494-2-joel@jms.id.au>

Hello,

On 03/10/2018 15:31:54+0200, Joel Stanley wrote:
> +static int aspeed_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct aspeed_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int cent, year, mon, day, hour, min, sec;
> +	unsigned long flags;
> +	u32 reg1, reg2;
> +
> +	spin_lock_irqsave(&rtc->lock, flags);
> +
> +	do {
> +		reg2 = readl(rtc->base + RTC_YEAR);
> +		reg1 = readl(rtc->base + RTC_TIME);
> +	} while (reg2 != readl(rtc->base + RTC_YEAR));
> +
> +	day  = (reg1 >> 24) & 0x1f;
> +	hour = (reg1 >> 16) & 0x1f;
> +	min  = (reg1 >>  8) & 0x3f;
> +	sec  = (reg1 >>  0) & 0x3f;
> +	cent = (reg2 >> 16) & 0x1f;
> +	year = (reg2 >>  8) & 0x7f;
> +	/*
> +	 * Month is 1-12 in hardware, and 0-11 in struct rtc_time, however we
> +	 * are using mktime64 which is 1-12, so no adjustment is necessary
> +	 */
> +	mon  = (reg2 >>  0) & 0x0f;
> +
> +	rtc_time64_to_tm(mktime64(cent * 100 + year, mon, day, hour, min, sec),
> +			tm);
> +

This is quite wasteful. You already have the broken out time. Why don't
you directly fill the tm struct?

> +static int aspeed_rtc_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	struct aspeed_rtc *rtc;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	rtc->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(rtc->base))
> +		return PTR_ERR(rtc->base);
> +
> +	platform_set_drvdata(pdev, rtc);
> +
> +	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> +						&aspeed_rtc_ops, THIS_MODULE);
> +

Please use devm_rtc_allocate_device to allocate the rtc and then
register it with rtc_register_device. Please also fill
rtc->range_{min,max} before the registration.

> +	if (IS_ERR(rtc->rtc_dev))
> +		return PTR_ERR(rtc->rtc_dev);
> +
> +	spin_lock_init(&rtc->lock);
> +
> +	/* Enable RTC and clear the unlock bit */
> +	writel(RTC_ENABLE, rtc->base + RTC_CTRL);
> +

Maybe this should only be done in set_time so you can know whether the
time that is read in read_time has a chance to be valid.

For example you could return -EINVAL when RTC_ENABLE is not set if this
bit is readable.

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

WARNING: multiple messages have this Message-ID (diff)
From: alexandre.belloni@bootlin.com (Alexandre Belloni)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] rtc: Add ASPEED RTC driver
Date: Thu, 4 Oct 2018 20:37:00 +0200	[thread overview]
Message-ID: <20181004183700.GA5626@piout.net> (raw)
In-Reply-To: <20181003133155.27494-2-joel@jms.id.au>

Hello,

On 03/10/2018 15:31:54+0200, Joel Stanley wrote:
> +static int aspeed_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct aspeed_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int cent, year, mon, day, hour, min, sec;
> +	unsigned long flags;
> +	u32 reg1, reg2;
> +
> +	spin_lock_irqsave(&rtc->lock, flags);
> +
> +	do {
> +		reg2 = readl(rtc->base + RTC_YEAR);
> +		reg1 = readl(rtc->base + RTC_TIME);
> +	} while (reg2 != readl(rtc->base + RTC_YEAR));
> +
> +	day  = (reg1 >> 24) & 0x1f;
> +	hour = (reg1 >> 16) & 0x1f;
> +	min  = (reg1 >>  8) & 0x3f;
> +	sec  = (reg1 >>  0) & 0x3f;
> +	cent = (reg2 >> 16) & 0x1f;
> +	year = (reg2 >>  8) & 0x7f;
> +	/*
> +	 * Month is 1-12 in hardware, and 0-11 in struct rtc_time, however we
> +	 * are using mktime64 which is 1-12, so no adjustment is necessary
> +	 */
> +	mon  = (reg2 >>  0) & 0x0f;
> +
> +	rtc_time64_to_tm(mktime64(cent * 100 + year, mon, day, hour, min, sec),
> +			tm);
> +

This is quite wasteful. You already have the broken out time. Why don't
you directly fill the tm struct?

> +static int aspeed_rtc_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	struct aspeed_rtc *rtc;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	rtc->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(rtc->base))
> +		return PTR_ERR(rtc->base);
> +
> +	platform_set_drvdata(pdev, rtc);
> +
> +	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> +						&aspeed_rtc_ops, THIS_MODULE);
> +

Please use devm_rtc_allocate_device to allocate the rtc and then
register it with rtc_register_device. Please also fill
rtc->range_{min,max} before the registration.

> +	if (IS_ERR(rtc->rtc_dev))
> +		return PTR_ERR(rtc->rtc_dev);
> +
> +	spin_lock_init(&rtc->lock);
> +
> +	/* Enable RTC and clear the unlock bit */
> +	writel(RTC_ENABLE, rtc->base + RTC_CTRL);
> +

Maybe this should only be done in set_time so you can know whether the
time that is read in read_time has a chance to be valid.

For example you could return -EINVAL when RTC_ENABLE is not set if this
bit is readable.

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

  reply	other threads:[~2018-10-04 18:37 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-03 13:31 [PATCH 0/2] rtc: Add ASPEED RTC Joel Stanley
2018-10-03 13:31 ` Joel Stanley
2018-10-03 13:31 ` Joel Stanley
2018-10-03 13:31 ` [PATCH 1/2] rtc: Add ASPEED RTC driver Joel Stanley
2018-10-03 13:31   ` Joel Stanley
2018-10-03 13:31   ` Joel Stanley
2018-10-04 18:37   ` Alexandre Belloni [this message]
2018-10-04 18:37     ` Alexandre Belloni
2018-10-04 18:37     ` Alexandre Belloni
2018-10-03 13:31 ` [PATCH 2/2] dt-bindings: rtc: Add ASPEED description Joel Stanley
2018-10-03 13:31   ` Joel Stanley
2018-10-03 13:31   ` Joel Stanley
2018-10-04 18:37   ` Alexandre Belloni
2018-10-04 18:37     ` Alexandre Belloni
2018-10-04 18:37     ` Alexandre Belloni

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=20181004183700.GA5626@piout.net \
    --to=alexandre.belloni@bootlin.com \
    --cc=linux-aspeed@lists.ozlabs.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.