rtc: rzn1: Add OF match data to gate SUBU register access

The RZ/N1 RTC driver selects SCMP mode only when an optional xtal clock
is provided at a valid rate other than 32768 Hz. Without an xtal clock,
or when it runs at 32768 Hz, the driver uses SUBU mode.

However, the RTCA0SUBU register used by SUBU mode is not present on all
SoCs that integrate a similar variant of the RTC block. Allowing SUBU
mode on those variants would expose RTC offset operations that access a
non-existent register.

Add OF match data to describe whether the RTC supports the SUBU register.
Reject probe with -EOPNOTSUPP when SUBU mode would be selected on a
variant without SUBU support.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Suggested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://patch.msgid.link/20260821211032.13554-16-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
Lad Prabhakar 2026-08-21 22:10:30 +01:00 committed by Alexandre Belloni
parent 5ae93269d3
commit 38a3a3b099

View File

@ -19,6 +19,7 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
@ -66,6 +67,10 @@
#define RZN1_RTC_TIMEC 0x68
#define RZN1_RTC_CALC 0x6c
struct rzn1_rtc_data {
bool has_subu;
};
struct rzn1_rtc {
struct rtc_device *rtcdev;
void __iomem *base;
@ -405,6 +410,7 @@ static void rzn1_rtc_disable_hardware(void *data)
static int rzn1_rtc_probe(struct platform_device *pdev)
{
const struct rzn1_rtc_data *data;
struct device *dev = &pdev->dev;
unsigned long rate = 32768;
struct rzn1_rtc *rtc;
@ -412,6 +418,10 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
struct clk *xtal;
int irq, ret;
data = of_device_get_match_data(dev);
if (!data)
return -ENODEV;
rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
@ -455,8 +465,12 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
if (rate < 32000 || rate > BIT(22))
return -EOPNOTSUPP;
if (rate != 32768)
if (rate != 32768 || !data->has_subu)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
} else if (!data->has_subu) {
/* xtal is NULL here */
return dev_err_probe(dev, -EOPNOTSUPP,
"No valid XTAL provided and SUBU mode not supported\n");
}
/* Calculate the duration of two RTC_PCLK clock cycles */
@ -509,8 +523,12 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
return devm_rtc_register_device(rtc->rtcdev);
}
static const struct rzn1_rtc_data rzn1_rtc_rzn1_data = {
.has_subu = true,
};
static const struct of_device_id rzn1_rtc_of_match[] = {
{ .compatible = "renesas,rzn1-rtc" },
{ .compatible = "renesas,rzn1-rtc", .data = &rzn1_rtc_rzn1_data },
{},
};
MODULE_DEVICE_TABLE(of, rzn1_rtc_of_match);