linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: dang.huynh@mainlining.org
Cc: Manivannan Sadhasivam <mani@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Bartosz Golaszewski <brgl@bgdev.pl>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Sebastian Reichel <sre@kernel.org>, Vinod Koul <vkoul@kernel.org>,
	Kees Cook <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	linux-unisoc@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-rtc@vger.kernel.org, linux-clk@vger.kernel.org,
	linux-pm@vger.kernel.org, dmaengine@vger.kernel.org,
	linux-hardening@vger.kernel.org, linux-mmc@vger.kernel.org
Subject: Re: [PATCH 06/25] rtc: Add driver for RDA Micro SoC
Date: Thu, 6 Nov 2025 23:42:52 +0100	[thread overview]
Message-ID: <2025110622425227de2cac@mail.local> (raw)
In-Reply-To: <20250917-rda8810pl-drivers-v1-6-9ca9184ca977@mainlining.org>

Hello,

There are checkpatch --strict issues, please fix them.


On 17/09/2025 03:25:03+0700, Dang Huynh via B4 Relay wrote:
>  MAINTAINERS           |   6 +
>  drivers/rtc/Kconfig   |  11 ++
>  drivers/rtc/Makefile  |   1 +
>  drivers/rtc/rtc-rda.c | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++

Unless you can guarantee this driver will support all the future RDA
SoC RTCs, the filename needs to be SoC specific.

> +config RTC_DRV_RDA
> +	tristate "RDA Micro RTC"
> +	depends on ARCH_RDA || COMPILE_TEST
> +	select REGMAP_MMIO
> +	help
> +	  If you say yes here you get support for the built-in RTC on
> +	  RDA Micro SoC.

You probably also need to list which ones are supported.

> +static int rda_rtc_settime(struct device *dev, struct rtc_time *tm)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +	u32 high, low;
> +	int ret;
> +
> +	ret = rtc_valid_tm(tm);
> +	if (ret < 0)
> +		return ret;

The RTC core will never pass an invalid rtc_tm, this check is useless.

> +
> +	/*
> +	 * The number of years since 1900 in kernel,
> +	 * but it is defined since 2000 by HW.
> +	 * The number of mons' range is from 0 to 11 in kernel,
> +	 * but it is defined from 1 to 12 by HW.

This comment is not super useful as this is super common in the RTC
drivers,. If you want to keep it, please fix it.

> +	 */
> +	low = FIELD_PREP(RDA_SEC_MASK, tm->tm_sec) |
> +		FIELD_PREP(RDA_MIN_MASK, tm->tm_min) |
> +		FIELD_PREP(RDA_HRS_MASK, tm->tm_hour);
> +
> +	high = FIELD_PREP(RDA_MDAY_MASK, tm->tm_mday) |
> +		FIELD_PREP(RDA_MON_MASK, tm->tm_mon + 1) |
> +		FIELD_PREP(RDA_YEAR_MASK, tm->tm_year - 100) |
> +		FIELD_PREP(RDA_WDAY_MASK, tm->tm_wday);
> +
> +	ret = regmap_write(rtc->regmap, RDA_RTC_CAL_LOAD_LOW_REG, low);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to update RTC low register: %d\n", ret);

This needs to be a dev_dbg or removed.

> +		return ret;
> +	}
> +
> +	ret = regmap_write(rtc->regmap, RDA_RTC_CAL_LOAD_HIGH_REG, high);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to update RTC low register: %d\n", ret);

Ditto

> +		return ret;
> +	}
> +
> +	ret = regmap_update_bits(rtc->regmap, RDA_RTC_CMD_REG, RDA_RTC_CMD_CAL_LOAD, 1);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to update RTC cal load register: %d\n", ret);

Ditto

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int rda_rtc_readtime(struct device *dev, struct rtc_time *tm)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int high, low;
> +	int ret;
> +
> +	/*
> +	 * Check if RTC data is valid.
> +	 *
> +	 * When this bit is set, it means the data in the RTC is invalid
> +	 * or not configured.
> +	 */
> +	ret = regmap_test_bits(rtc->regmap, RDA_RTC_STA_REG, RDA_RTC_STA_NOT_PROG);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to read RTC status: %d\n", ret);

dev_dbg

> +		return ret;
> +	} else if (ret > 0)
> +		return -EINVAL;
> +
> +	ret = regmap_read(rtc->regmap, RDA_RTC_CUR_LOAD_HIGH_REG, &high);
> +	if (ret) {
> +		dev_err(dev, "Failed to read RTC high reg: %d\n", ret);

Ditto

> +		return ret;
> +	}
> +
> +	ret = regmap_read(rtc->regmap, RDA_RTC_CUR_LOAD_LOW_REG, &low);
> +	if (ret) {
> +		dev_err(dev, "Failed to read RTC low reg: %d\n", ret);

Ditto

> +		return ret;
> +	}
> +
> +	tm->tm_sec = FIELD_GET(RDA_SEC_MASK, low);
> +	tm->tm_min = FIELD_GET(RDA_MIN_MASK, low);
> +	tm->tm_hour = FIELD_GET(RDA_HRS_MASK, low);
> +	tm->tm_mday = FIELD_GET(RDA_MDAY_MASK, high);
> +	tm->tm_mon = FIELD_GET(RDA_MON_MASK, high);
> +	tm->tm_year = FIELD_GET(RDA_YEAR_MASK, high);
> +	tm->tm_wday = FIELD_GET(RDA_WDAY_MASK, high);
> +
> +	/*
> +	 * The number of years since 1900 in kernel,
> +	 * but it is defined since 2000 by HW.
> +	 */
> +	tm->tm_year += 100;
> +	/*
> +	 * The number of mons' range is from 0 to 11 in kernel,
> +	 * but it is defined from 1 to 12 by HW.
> +	 */

You can probably drop both comments.

> +	tm->tm_mon -= 1;
> +
> +	return 0;
> +}
> +
> +static int rda_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +	struct rtc_time *tm = &alrm->time;
> +	unsigned int high, low;
> +	int ret;
> +
> +	ret = regmap_read(rtc->regmap, RDA_RTC_ALARM_HIGH_REG, &high);
> +	if (ret) {
> +		dev_err(dev, "Failed to read alarm low reg: %d\n", ret);

Just to be clear, the driver is super verbose with all those dev_err.
Strings are bloating the kernel and those string will probably never be
seen by any user and event if they are seen, the user doesn't have any
other action to do other than retrying. Please remove them of move them
to dev_dbg

> +		return ret;
> +	}
> +
> +	ret = regmap_read(rtc->regmap, RDA_RTC_ALARM_LOW_REG, &low);
> +	if (ret) {
> +		dev_err(dev, "Failed to read alarm low reg: %d\n", ret);
> +		return ret;
> +	}
> +
> +	tm->tm_sec = FIELD_GET(RDA_SEC_MASK, low);
> +	tm->tm_min = FIELD_GET(RDA_MIN_MASK, low);
> +	tm->tm_hour = FIELD_GET(RDA_HRS_MASK, low);
> +	tm->tm_mday = FIELD_GET(RDA_MDAY_MASK, high);
> +	tm->tm_mon = FIELD_GET(RDA_MON_MASK, high);
> +	tm->tm_year = FIELD_GET(RDA_YEAR_MASK, high);
> +	tm->tm_wday = FIELD_GET(RDA_WDAY_MASK, high);
> +
> +	/*
> +	 * The number of years since 1900 in kernel,
> +	 * but it is defined since 2000 by HW.
> +	 */
> +	tm->tm_year += 100;
> +	/*
> +	 * The number of mons' range is from 0 to 11 in kernel,
> +	 * but it is defined from 1 to 12 by HW.
> +	 */
> +	tm->tm_mon -= 1;
> +
> +	return 0;
> +}
> +
> +static int rda_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +
> +	if (enabled)
> +		return regmap_update_bits(rtc->regmap, RDA_RTC_CMD_REG,
> +				RDA_RTC_CMD_ALARM_ENABLE, 1);
> +
> +	return regmap_update_bits(rtc->regmap, RDA_RTC_CMD_REG,
> +			RDA_RTC_CMD_ALARM_DISABLE, 1);

Wow, this is super weird, so you have one bit to enable and one to
disable the alarm. Is RDA_RTC_CMD_REG write only?

> +}
> +
> +static int rda_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +	struct rtc_time *tm = &alrm->time;
> +	u32 high, low;
> +	int ret;
> +
> +	ret = rtc_valid_tm(tm);
> +	if (ret < 0)
> +		return ret;
> +

tm will never be invalid

> +	/* TODO: Check if it's necessary to disable IRQ first */

I'd say probably not ;)

> +	rda_rtc_alarm_irq_enable(dev, 0);
> +
> +	/*
> +	 * The number of years since 1900 in kernel,
> +	 * but it is defined since 2000 by HW.
> +	 * The number of mons' range is from 0 to 11 in kernel,
> +	 * but it is defined from 1 to 12 by HW.
> +	 */

This is still the same comment...

> +	low = FIELD_PREP(RDA_SEC_MASK, tm->tm_sec) |
> +		FIELD_PREP(RDA_MIN_MASK, tm->tm_min) |
> +		FIELD_PREP(RDA_HRS_MASK, tm->tm_hour);
> +
> +	high = FIELD_PREP(RDA_MDAY_MASK, tm->tm_mday) |
> +		FIELD_PREP(RDA_MON_MASK, tm->tm_mon + 1) |
> +		FIELD_PREP(RDA_YEAR_MASK, tm->tm_year - 100) |
> +		FIELD_PREP(RDA_WDAY_MASK, tm->tm_wday);
> +
> +
> +	ret = regmap_write(rtc->regmap, RDA_RTC_ALARM_LOW_REG, low);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set low alarm register: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = regmap_write(rtc->regmap, RDA_RTC_ALARM_HIGH_REG, high);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set low alarm register: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = regmap_update_bits(rtc->regmap, RDA_RTC_CMD_REG, RDA_RTC_CMD_ALARM_LOAD, 1);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set alarm register: %d\n", ret);
> +		return ret;
> +	}
> +
> +	dev_dbg(dev, "Alarm set: %4d-%02d-%02d %02d:%02d:%02d\n",
> +			2000 + (tm->tm_year - 100), tm->tm_mon + 1, tm->tm_mday,
> +			tm->tm_hour, tm->tm_min, tm->tm_sec);

You probably want to use %ptR or drop this as we have a tracepoint just
after.

> +
> +	return 0;
> +}
> +
> +static int rda_rtc_proc(struct device *dev, struct seq_file *seq)
> +{
> +	struct rda_rtc *rtc = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = regmap_test_bits(rtc->regmap, RDA_RTC_STA_REG, RDA_RTC_STA_ALARM_ENABLE);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to read alarm status: %d\n", ret);
> +		return ret;
> +	}
> +
> +	seq_printf(seq, "alarm enable\t: %s\n", (ret > 0) ? "yes" : "no");
> +
> +	return 0;
> +}

Drop this function, this interface is obsolete

> +
> +static const struct rtc_class_ops rda_rtc_ops = {
> +	.read_time = rda_rtc_readtime,
> +	.set_time = rda_rtc_settime,
> +	.read_alarm = rda_rtc_readalarm,
> +	.set_alarm = rda_rtc_setalarm,
> +	.proc = rda_rtc_proc,
> +	.alarm_irq_enable = rda_rtc_alarm_irq_enable,
> +};
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int rda_rtc_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +	/* TODO: Check if it's okay to turn on alarm IRQ when it's not set */
> +	return rda_rtc_alarm_irq_enable(&pdev->dev, 1);
> +}
> +
> +static int rda_rtc_resume(struct platform_device *pdev)
> +{
> +	/* If alarms were left, we turn them off. */
> +	return rda_rtc_alarm_irq_enable(&pdev->dev, 0);
> +}

Let userspace enabling/disabling alarm, the kernel must not decide to
enable or disable them which fixes your TODO

> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(rda_rtc_pm_ops, rda_rtc_suspend, rda_rtc_resume);
> +
> +static const struct regmap_config regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +};
> +
> +static int rda_rtc_probe(struct platform_device *pdev)
> +{
> +	struct rda_rtc *rda_rtc;
> +	void __iomem *base;
> +
> +	rda_rtc = devm_kzalloc(&pdev->dev, sizeof(*rda_rtc), GFP_KERNEL);
> +	if (!rda_rtc)
> +		return -ENOMEM;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(base),
> +				"failed to remap resource\n");
> +
> +	rda_rtc->regmap = devm_regmap_init_mmio(&pdev->dev, base, &regmap_config);
> +	if (!rda_rtc->regmap)
> +		return dev_err_probe(&pdev->dev, PTR_ERR(rda_rtc->regmap),
> +				"can't find regmap\n");
> +
> +	rda_rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
> +	if (IS_ERR(rda_rtc->rtc_dev))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(rda_rtc->rtc_dev),
> +				"failed to allocate rtc device\n");
> +
> +	rda_rtc->rtc_dev->ops = &rda_rtc_ops;
> +	rda_rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
> +	rda_rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_2127;
> +
> +	platform_set_drvdata(pdev, rda_rtc);
> +
> +	return devm_rtc_register_device(rda_rtc->rtc_dev);
> +}
> +
> +static const struct of_device_id rda_rtc_id_table[] = {
> +	{ .compatible = "rda,8810pl-rtc", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, rda_rtc_id_table);
> +
> +static struct platform_driver rda_rtc_driver = {
> +	.probe = rda_rtc_probe,
> +	.driver = {
> +		.name = "rtc-rda",
> +		.pm = &rda_rtc_pm_ops,
> +		.of_match_table = rda_rtc_id_table,
> +	},
> +};
> +module_platform_driver(rda_rtc_driver);
> +
> +MODULE_AUTHOR("Dang Huynh <dang.huynh@mainlining.org>");
> +MODULE_DESCRIPTION("RDA Micro RTC driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.51.0
> 
> 

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

  parent reply	other threads:[~2025-11-06 22:43 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-16 20:24 [PATCH 00/25] RDA8810PL Clock, RTC and MMC driver Dang Huynh via B4 Relay
2025-09-16 20:24 ` [PATCH 01/25] ARM: dts: unisoc: rda8810pl: Add label to GPIO nodes Dang Huynh via B4 Relay
2025-09-17  0:39   ` Krzysztof Kozlowski
2025-09-16 20:24 ` [PATCH 02/25] drivers: gpio: rda: Make IRQ optional Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 03/25] dt-bindings: gpio: rda: Make interrupts optional Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 04/25] rtc: Add timestamp for the end of 2127 Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 05/25] dt-bindings: rtc: Add RDA Micro RDA8810PL RTC Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 06/25] rtc: Add driver for RDA Micro SoC Dang Huynh via B4 Relay
2025-09-19 13:59   ` kernel test robot
2025-11-06 22:42   ` Alexandre Belloni [this message]
2025-09-16 20:25 ` [PATCH 07/25] ARM: dts: unisoc: rda8810pl: Enable Real-Time Clock Dang Huynh via B4 Relay
2025-09-17  0:40   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 08/25] ARM: dts: unisoc: rda8810pl: Enable ARM PMU Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 09/25] dt-bindings: clock: Add RDA Micro RDA8810PL clock/reset controller Dang Huynh via B4 Relay
2025-09-17  0:43   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 10/25] drivers: clk: Add Clock and Reset Driver for RDA Micro RDA8810PL SoC Dang Huynh via B4 Relay
2025-09-20  4:50   ` Stephen Boyd
2025-09-16 20:25 ` [PATCH 11/25] dts: unisoc: rda8810pl: Enable clock/reset driver Dang Huynh via B4 Relay
2025-09-17  0:41   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 12/25] dts: unisoc: rda8810pl: Add OPP for CPU and define L2 cache Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 13/25] dts: unisoc: orangepi: Disable UART with no users Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 14/25] dt-bindings: power: reset: Add RDA Micro Modem Reset Dang Huynh via B4 Relay
2025-09-17  0:44   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 15/25] power: reset: Add basic power reset driver for RDA8810PL Dang Huynh via B4 Relay
2025-09-17  0:45   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 16/25] dts: unisoc: rda8810pl: Enable modem reset Dang Huynh via B4 Relay
2025-09-17  0:46   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 17/25] drivers: gpio: rda: Make direction register unreadable Dang Huynh via B4 Relay
2025-09-17  8:00   ` Bartosz Golaszewski
2025-09-16 20:25 ` [PATCH 18/25] dt-bindings: dma: Add RDA IFC DMA Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 19/25] dmaengine: Add RDA IFC driver Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 20/25] dts: unisoc: rda8810pl: Enable IFC Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 21/25] dt-bindings: mmc: Add RDA SDMMC controller Dang Huynh via B4 Relay
2025-09-17  0:00   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 22/25] mmc: host: Add RDA Micro SD/MMC driver Dang Huynh via B4 Relay
2025-09-17  0:48   ` Krzysztof Kozlowski
2025-09-16 20:25 ` [PATCH 23/25] dts: unisoc: rda8810pl: Add SDMMC controllers Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 24/25] dts: unisoc: orangepi-2g: Enable SD Card Dang Huynh via B4 Relay
2025-09-16 20:25 ` [PATCH 25/25] dts: unisoc: orangepi-i96: " Dang Huynh via B4 Relay
2025-09-17 10:03 ` [PATCH 00/25] RDA8810PL Clock, RTC and MMC driver Manivannan Sadhasivam
2025-09-18  5:02   ` Dang Huynh
  -- strict thread matches above, loose matches on Subject: below --
2025-09-16 20:07 Dang Huynh
2025-09-16 20:07 ` [PATCH 06/25] rtc: Add driver for RDA Micro SoC Dang Huynh

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=2025110622425227de2cac@mail.local \
    --to=alexandre.belloni@bootlin.com \
    --cc=brgl@bgdev.pl \
    --cc=conor+dt@kernel.org \
    --cc=dang.huynh@mainlining.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=gustavoars@kernel.org \
    --cc=kees@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=linux-unisoc@lists.infradead.org \
    --cc=mani@kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=sre@kernel.org \
    --cc=ulf.hansson@linaro.org \
    --cc=vkoul@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).