summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/Kconfig8
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c1
-rw-r--r--drivers/rtc/rtc-brcmstb-waketimer.c1
-rw-r--r--drivers/rtc/rtc-ds1307.c2
-rw-r--r--drivers/rtc/rtc-ds1343.c4
-rw-r--r--drivers/rtc/rtc-gamecube.c4
-rw-r--r--drivers/rtc/rtc-hym8563.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c2
-rw-r--r--drivers/rtc/rtc-mv.c41
-rw-r--r--drivers/rtc/rtc-nct3018y.c2
-rw-r--r--drivers/rtc/rtc-pcf2127.c7
-rw-r--r--drivers/rtc/rtc-pcf85063.c2
-rw-r--r--drivers/rtc/rtc-pcf85363.c17
-rw-r--r--drivers/rtc/rtc-pcf8563.c6
-rw-r--r--drivers/rtc/rtc-rv3028.c2
-rw-r--r--drivers/rtc/rtc-rv3032.c2
-rw-r--r--drivers/rtc/rtc-rzn1.c197
-rw-r--r--drivers/rtc/rtc-s32g.c1
-rw-r--r--drivers/rtc/rtc-spacemit-p1.c5
-rw-r--r--drivers/rtc/rtc-st-lpc.c9
-rw-r--r--drivers/rtc/rtc-zynqmp.c7
21 files changed, 168 insertions, 154 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 01def8231873..05b9233b9418 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1635,10 +1635,11 @@ config RTC_DRV_RS5C313
config RTC_DRV_RZN1
tristate "Renesas RZ/N1 RTC"
- depends on ARCH_RZN1 || COMPILE_TEST
+ depends on ARCH_RENESAS || COMPILE_TEST
depends on OF && HAS_IOMEM
help
- If you say yes here you get support for the Renesas RZ/N1 RTC.
+ If you say yes here you get support for the RTC initially found on
+ Renesas RZ/N1 SoCs.
config RTC_DRV_GENERIC
tristate "Generic RTC support"
@@ -2106,7 +2107,8 @@ config RTC_DRV_MACSMC
config RTC_DRV_MSC313
tristate "MStar MSC313 RTC"
- depends on ARCH_MSTARV7 || COMPILE_TEST
+ depends on ARCH_MSTARV7 || COMPILE_TEST
+ default ARCH_MSTARV7
help
If you say yes here you get support for the Mstar MSC313e On-Chip
Real Time Clock.
diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index b75f4f665076..eb6d267c2ec3 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -549,6 +549,7 @@ static const struct i2c_device_id abeoz9_id[] = {
{ .name = "abeoz9" },
{ }
};
+MODULE_DEVICE_TABLE(i2c, abeoz9_id);
static struct i2c_driver abeoz9_driver = {
.driver = {
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index fb47c32ab5ff..55c15aad42cf 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -413,6 +413,7 @@ static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
{ .compatible = "brcm,brcmstb-waketimer" },
{ /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, brcmstb_waketmr_of_match);
static struct platform_driver brcmstb_waketmr_driver = {
.probe = brcmstb_waketmr_probe,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index fd3858b6569e..522f7eef3b4a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -661,7 +661,7 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
if (ret < 0)
return ret;
- ctl[0] &= RX8130_REG_EXTENSION_WADA;
+ ctl[0] |= RX8130_REG_EXTENSION_WADA;
ctl[1] &= ~RX8130_REG_FLAG_AF;
ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index aa9500791b7e..54f6af7886a8 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -120,7 +120,7 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
return count;
}
-static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter,
+static DEVICE_ATTR(glitch_filter, 0644, ds1343_show_glitchfilter,
ds1343_store_glitchfilter);
static int ds1343_nvram_write(void *priv, unsigned int off, void *val,
@@ -183,7 +183,7 @@ static ssize_t ds1343_show_tricklecharger(struct device *dev,
return sprintf(buf, "%s %s\n", diodes, resistors);
}
-static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
+static DEVICE_ATTR(trickle_charger, 0444, ds1343_show_tricklecharger, NULL);
static struct attribute *ds1343_attrs[] = {
&dev_attr_glitch_filter.attr,
diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c
index 045d5d45ab4b..889028cecf4a 100644
--- a/drivers/rtc/rtc-gamecube.c
+++ b/drivers/rtc/rtc-gamecube.c
@@ -355,9 +355,7 @@ static int gamecube_rtc_probe(struct platform_device *pdev)
rtc->range_max = U32_MAX;
rtc->ops = &gamecube_rtc_ops;
- devm_rtc_register_device(rtc);
-
- return 0;
+ return devm_rtc_register_device(rtc);
}
static const struct of_device_id gamecube_rtc_of_match[] = {
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index 3156aa5f2d9f..1d52cc3def02 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -376,8 +376,8 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
{
struct i2c_client *client = hym8563->client;
struct device_node *node = client->dev.of_node;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
int ret;
ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT,
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 3c8c379392c1..ec86ca3f2c4c 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -574,8 +574,8 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80)
struct i2c_client *client = m41t80->client;
struct device_node *node = client->dev.of_node;
struct device_node *fixed_clock;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
int ret;
fixed_clock = of_get_child_by_name(node, "clock");
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index f88976fd6d5d..db64c459ee19 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -219,17 +219,15 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
- pdata->clk = devm_clk_get(&pdev->dev, NULL);
- /* Not all SoCs require a clock.*/
- if (!IS_ERR(pdata->clk))
- clk_prepare_enable(pdata->clk);
+ pdata->clk = devm_clk_get_optional_prepared(&pdev->dev, NULL);
+ if (IS_ERR(pdata->clk))
+ return PTR_ERR(pdata->clk);
/* make sure the 24 hour mode is enabled */
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time & RTC_HOURS_12H_MODE) {
dev_err(&pdev->dev, "12 Hour mode is enabled but not supported.\n");
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
/* make sure it is actually functional */
@@ -238,8 +236,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time == 0x01000000) {
dev_err(&pdev->dev, "internal RTC not ticking\n");
- ret = -ENODEV;
- goto out;
+ return -ENODEV;
}
}
@@ -249,8 +246,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc)) {
- ret = PTR_ERR(pdata->rtc);
- goto out;
+ return PTR_ERR(pdata->rtc);
}
if (pdata->irq >= 0) {
@@ -264,7 +260,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
}
if (pdata->irq >= 0)
- device_init_wakeup(&pdev->dev, true);
+ devm_device_init_wakeup(&pdev->dev);
else
clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
@@ -275,24 +271,10 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
ret = devm_rtc_register_device(pdata->rtc);
if (!ret)
return 0;
-out:
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
return ret;
}
-static void __exit mv_rtc_remove(struct platform_device *pdev)
-{
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- if (pdata->irq >= 0)
- device_init_wakeup(&pdev->dev, false);
-
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
-}
-
#ifdef CONFIG_OF
static const struct of_device_id rtc_mv_of_match_table[] = {
{ .compatible = "marvell,orion-rtc", },
@@ -323,14 +305,7 @@ static int mv_rtc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(mv_rtc_pm_ops, mv_rtc_suspend, mv_rtc_resume);
-/*
- * mv_rtc_remove() lives in .exit.text. For drivers registered via
- * module_platform_driver_probe() this is ok because they cannot get unbound at
- * runtime. So mark the driver struct with __refdata to prevent modpost
- * triggering a section mismatch warning.
- */
-static struct platform_driver mv_rtc_driver __refdata = {
- .remove = __exit_p(mv_rtc_remove),
+static struct platform_driver mv_rtc_driver = {
.driver = {
.name = "rtc-mv",
.of_match_table = of_match_ptr(rtc_mv_of_match_table),
diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c
index 700a395fad3a..2f7ad57057a4 100644
--- a/drivers/rtc/rtc-nct3018y.c
+++ b/drivers/rtc/rtc-nct3018y.c
@@ -459,8 +459,8 @@ static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y)
{
struct i2c_client *client = nct3018y->client;
struct device_node *node = client->dev.of_node;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
init.name = "nct3018y-clkout";
init.ops = &nct3018y_clkout_ops;
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index 1995e9f2756d..ff2023908f5a 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -1184,12 +1184,7 @@ static int pcf2127_configure_interrupt_pins(struct device *dev)
if (ret)
return ret;
- ret = regmap_write(pcf2127->regmap,
- PCF2131_REG_INT_A_MASK2, 0);
- if (ret)
- return ret;
-
- return ret;
+ return regmap_write(pcf2127->regmap, PCF2131_REG_INT_A_MASK2, 0);
}
static int pcf2127_probe(struct device *dev, struct regmap *regmap,
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 01e209d88f5f..8cb9ffc73f6d 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -498,7 +498,7 @@ static const struct clk_ops pcf85063_clkout_ops = {
static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
{
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = pcf85063->rtc->dev.parent->of_node;
struct device_node *fixed_clock;
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index 540042b9eec8..ccc7834e5759 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -426,8 +426,8 @@ static int pcf85363_probe(struct i2c_client *client)
err = pcf85363_load_capacitance(pcf85363, client->dev.of_node);
if (err < 0)
- dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
- err);
+ return dev_err_probe(&client->dev, err,
+ "failed to set xtal load capacitance\n");
pcf85363->rtc->ops = &rtc_ops;
pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
@@ -436,9 +436,16 @@ static int pcf85363_probe(struct i2c_client *client)
wakeup_source = device_property_read_bool(&client->dev,
"wakeup-source");
if (client->irq > 0 || wakeup_source) {
- regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
- regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
- PIN_IO_INTAPM, PIN_IO_INTA_OUT);
+ err = regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
+ if (err)
+ return dev_err_probe(&client->dev, err,
+ "failed to clear flags\n");
+
+ err = regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
+ PIN_IO_INTAPM, PIN_IO_INTA_OUT);
+ if (err)
+ return dev_err_probe(&client->dev, err,
+ "failed to set interrupt pin mode\n");
}
if (client->irq > 0) {
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 81d13733b1e9..7eebdb058067 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -425,7 +425,7 @@ static const struct clk_ops pcf8563_clkout_ops = {
static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
{
struct device_node *node = pcf8563->rtc->dev.parent->of_node;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct clk *clk;
int ret;
@@ -449,7 +449,9 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
clk = devm_clk_register(&pcf8563->rtc->dev, &pcf8563->clkout_hw);
if (!IS_ERR(clk))
- of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ devm_of_clk_add_hw_provider(pcf8563->rtc->dev.parent,
+ of_clk_hw_simple_get,
+ &pcf8563->clkout_hw);
return clk;
}
diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c
index d96f6bb68850..d25e33d0835e 100644
--- a/drivers/rtc/rtc-rv3028.c
+++ b/drivers/rtc/rtc-rv3028.c
@@ -816,7 +816,7 @@ static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
{
int ret;
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = client->dev.of_node;
ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c
index 6bafdec637ae..687faaef42b2 100644
--- a/drivers/rtc/rtc-rv3032.c
+++ b/drivers/rtc/rtc-rv3032.c
@@ -752,7 +752,7 @@ static int rv3032_clkout_register_clk(struct rv3032_data *rv3032,
{
int ret;
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = client->dev.of_node;
ret = regmap_update_bits(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0);
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 305f10a8a85b..b9d69ebdd224 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -12,10 +12,13 @@
*/
#include <linux/bcd.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
@@ -38,14 +41,18 @@
#define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST)
#define RZN1_RTC_TIME 0x30
-#define RZN1_RTC_TIME_MIN_SHIFT 8
-#define RZN1_RTC_TIME_HOUR_SHIFT 16
+#define RZN1_RTC_TIME_SEC GENMASK(7, 0)
+#define RZN1_RTC_TIME_MIN GENMASK(15, 8)
+#define RZN1_RTC_TIME_HOUR GENMASK(23, 16)
+
#define RZN1_RTC_CAL 0x34
-#define RZN1_RTC_CAL_DAY_SHIFT 8
-#define RZN1_RTC_CAL_MON_SHIFT 16
-#define RZN1_RTC_CAL_YEAR_SHIFT 24
+#define RZN1_RTC_CAL_WDAY GENMASK(7, 0)
+#define RZN1_RTC_CAL_DAY GENMASK(15, 8)
+#define RZN1_RTC_CAL_MON GENMASK(23, 16)
+#define RZN1_RTC_CAL_YEAR GENMASK(31, 24)
#define RZN1_RTC_SUBU 0x38
+#define RZN1_RTC_SUBU_RTCA0FX GENMASK(5, 0)
#define RZN1_RTC_SUBU_DEV BIT(7)
#define RZN1_RTC_SUBU_DECR BIT(6)
@@ -59,6 +66,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;
@@ -69,6 +80,7 @@ struct rzn1_rtc {
*/
spinlock_t ctl1_access_lock;
struct rtc_time tm_alarm;
+ unsigned long sync_time;
};
static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm)
@@ -76,15 +88,15 @@ static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm
u32 val;
val = readl(rtc->base + RZN1_RTC_TIMEC);
- tm->tm_sec = bcd2bin(val);
- tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT);
- tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT);
+ tm->tm_sec = bcd2bin(FIELD_GET(RZN1_RTC_TIME_SEC, val));
+ tm->tm_min = bcd2bin(FIELD_GET(RZN1_RTC_TIME_MIN, val));
+ tm->tm_hour = bcd2bin(FIELD_GET(RZN1_RTC_TIME_HOUR, val));
val = readl(rtc->base + RZN1_RTC_CALC);
- tm->tm_wday = val & 0x0f;
- tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT);
- tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1;
- tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100;
+ tm->tm_wday = FIELD_GET(RZN1_RTC_CAL_WDAY, val);
+ tm->tm_mday = bcd2bin(FIELD_GET(RZN1_RTC_CAL_DAY, val));
+ tm->tm_mon = bcd2bin(FIELD_GET(RZN1_RTC_CAL_MON, val)) - 1;
+ tm->tm_year = bcd2bin(FIELD_GET(RZN1_RTC_CAL_YEAR, val)) + 100;
}
static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)
@@ -119,23 +131,23 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Hold the counter if it was counting up */
writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
- /* Wait for the counter to stop: two 32k clock cycles */
- usleep_range(61, 100);
+ /* Wait 2-4 RTC_PCLK clock cycles for the counter to stop */
+ usleep_range(rtc->sync_time, rtc->sync_time * 2);
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val,
val & RZN1_RTC_CTL2_WST, 0, 100);
if (ret)
return ret;
}
- val = bin2bcd(tm->tm_sec);
- val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT;
- val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_TIME_SEC, bin2bcd(tm->tm_sec)) |
+ FIELD_PREP(RZN1_RTC_TIME_MIN, bin2bcd(tm->tm_min)) |
+ FIELD_PREP(RZN1_RTC_TIME_HOUR, bin2bcd(tm->tm_hour));
writel(val, rtc->base + RZN1_RTC_TIME);
- val = tm->tm_wday;
- val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT;
- val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT;
- val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_CAL_WDAY, tm->tm_wday) |
+ FIELD_PREP(RZN1_RTC_CAL_DAY, bin2bcd(tm->tm_mday)) |
+ FIELD_PREP(RZN1_RTC_CAL_MON, bin2bcd(tm->tm_mon + 1)) |
+ FIELD_PREP(RZN1_RTC_CAL_YEAR, bin2bcd(tm->tm_year - 100));
writel(val, rtc->base + RZN1_RTC_CAL);
writel(0, rtc->base + RZN1_RTC_CTL2);
@@ -234,13 +246,24 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret)
return ret;
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ alrm->enabled = !!(ctl1 & (RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE));
+
min = readl(rtc->base + RZN1_RTC_ALM);
hour = readl(rtc->base + RZN1_RTC_ALH);
- wday = readl(rtc->base + RZN1_RTC_ALW);
tm->tm_sec = 0;
tm->tm_min = bcd2bin(min);
tm->tm_hour = bcd2bin(hour);
+
+ /*
+ * If wday is zero, no bit is set in RZN1_RTC_ALW. This is the
+ * register's power-on reset value.
+ */
+ wday = readl(rtc->base + RZN1_RTC_ALW);
+ if (!wday)
+ return 0;
+
delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7;
tm->tm_wday = fls(wday) - 1;
@@ -249,9 +272,6 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
rtc_time64_to_tm(alarm, tm);
}
- ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
- alrm->enabled = !!(ctl1 & (RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE));
-
return 0;
}
@@ -259,8 +279,7 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rzn1_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time, tm_now;
- unsigned long alarm, farest;
- unsigned int days_ahead, wday;
+ time64_t alarm, farest;
int ret;
ret = rzn1_rtc_read_time(dev, &tm_now);
@@ -270,16 +289,17 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* We cannot set alarms more than one week ahead */
farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max;
alarm = rtc_tm_to_time64(tm);
- if (time_after(alarm, farest))
+ if (alarm > farest)
return -ERANGE;
- /* Convert alarm day into week day */
- days_ahead = tm->tm_mday - tm_now.tm_mday;
- wday = (tm_now.tm_wday + days_ahead) % 7;
+ /* Disable alarm interrupts before reprogramming the alarm. */
+ ret = rzn1_rtc_alarm_irq_enable(dev, 0);
+ if (ret)
+ return ret;
writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM);
writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH);
- writel(BIT(wday), rtc->base + RZN1_RTC_ALW);
+ writel(BIT(tm->tm_wday), rtc->base + RZN1_RTC_ALW);
rtc->tm_alarm = alrm->time;
@@ -298,12 +318,12 @@ static int rzn1_rtc_read_offset(struct device *dev, long *offset)
val = readl(rtc->base + RZN1_RTC_SUBU);
ppb_per_step = val & RZN1_RTC_SUBU_DEV ? 1017 : 3051;
subtract = val & RZN1_RTC_SUBU_DECR;
- val &= 0x3F;
+ val = FIELD_GET(RZN1_RTC_SUBU_RTCA0FX, val);
if (!val)
*offset = 0;
else if (subtract)
- *offset = -(((~val) & 0x3F) + 1) * ppb_per_step;
+ *offset = -(((~val) & RZN1_RTC_SUBU_RTCA0FX) + 1) * ppb_per_step;
else
*offset = (val - 1) * ppb_per_step;
@@ -345,7 +365,7 @@ static int rzn1_rtc_set_offset(struct device *dev, long offset)
subu |= steps + 1;
} else {
subu |= RZN1_RTC_SUBU_DECR;
- subu |= (~(-steps - 1)) & 0x3F;
+ subu |= (~(-steps - 1)) & RZN1_RTC_SUBU_RTCA0FX;
}
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, ctl2,
@@ -376,15 +396,32 @@ static const struct rtc_class_ops rzn1_rtc_ops_scmp = {
.alarm_irq_enable = rzn1_rtc_alarm_irq_enable,
};
+static void rzn1_rtc_disable_hardware(void *data)
+{
+ struct device *dev = data;
+ struct rzn1_rtc *rtc = dev_get_drvdata(dev);
+
+ /* Disable all interrupts */
+ writel(0, rtc->base + RZN1_RTC_CTL1);
+
+ pm_runtime_put_sync(dev);
+}
+
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;
u32 val, scmp_val = 0;
struct clk *xtal;
- unsigned long rate;
int irq, ret;
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -ENODEV;
+
+ rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
@@ -392,13 +429,13 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
- return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n");
+ return dev_err_probe(dev, PTR_ERR(rtc->base), "Missing reg\n");
irq = platform_get_irq_byname(pdev, "alarm");
if (irq < 0)
return irq;
- rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
+ rtc->rtcdev = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtcdev))
return PTR_ERR(rtc->rtcdev);
@@ -406,38 +443,47 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099;
rtc->rtcdev->alarm_offset_max = 7 * 86400;
- ret = devm_pm_runtime_enable(&pdev->dev);
+ ret = devm_pm_runtime_enable(dev);
if (ret < 0)
return ret;
- ret = pm_runtime_resume_and_get(&pdev->dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
+ ret = devm_add_action_or_reset(dev, rzn1_rtc_disable_hardware, dev);
+ if (ret)
+ return ret;
+
/* Only switch to scmp if we have an xtal clock with a valid rate and != 32768 */
- xtal = devm_clk_get_optional(&pdev->dev, "xtal");
+ xtal = devm_clk_get_optional(dev, "xtal");
if (IS_ERR(xtal)) {
- ret = PTR_ERR(xtal);
- goto dis_runtime_pm;
+ return PTR_ERR(xtal);
} else if (xtal) {
rate = clk_get_rate(xtal);
- if (rate < 32000 || rate > BIT(22)) {
- ret = -EOPNOTSUPP;
- goto dis_runtime_pm;
- }
+ 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 */
+ rtc->sync_time = DIV_ROUND_UP(2 * USEC_PER_SEC, rate);
+
/* Disable controller during SUBU/SCMP setup */
val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
writel(val, rtc->base + RZN1_RTC_CTL0);
- /* Wait 2-4 32k clock cycles for the disabled controller */
+ /* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
- !(val & RZN1_RTC_CTL0_CEST), 62, 123);
+ !(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
+ rtc->sync_time * 2);
if (ret)
- goto dis_runtime_pm;
+ return ret;
/* Set desired modes leaving the controller disabled */
writel(RZN1_RTC_CTL0_AMPM | scmp_val, rtc->base + RZN1_RTC_CTL0);
@@ -457,53 +503,42 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
spin_lock_init(&rtc->ctl1_access_lock);
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
- if (ret) {
- dev_err(&pdev->dev, "RTC alarm interrupt not available\n");
- goto dis_runtime_pm;
- }
+ ret = devm_request_irq(dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
+ if (ret)
+ return dev_err_probe(dev, ret, "RTC alarm interrupt not available\n");
irq = platform_get_irq_byname_optional(pdev, "pps");
+ if (irq == -EPROBE_DEFER)
+ return irq;
if (irq >= 0)
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
+ ret = devm_request_irq(dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
if (irq < 0 || ret) {
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
- dev_warn(&pdev->dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
+ dev_warn(dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
}
- ret = devm_rtc_register_device(rtc->rtcdev);
- if (ret)
- goto dis_runtime_pm;
-
- return 0;
-
-dis_runtime_pm:
- pm_runtime_put(&pdev->dev);
-
- return ret;
+ return devm_rtc_register_device(rtc->rtcdev);
}
-static void rzn1_rtc_remove(struct platform_device *pdev)
-{
- struct rzn1_rtc *rtc = platform_get_drvdata(pdev);
-
- /* Disable all interrupts */
- writel(0, rtc->base + RZN1_RTC_CTL1);
+static const struct rzn1_rtc_data rzn1_rtc_rzt2h_data = {
+ .has_subu = false,
+};
- pm_runtime_put(&pdev->dev);
-}
+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,r9a09g077-rtc", .data = &rzn1_rtc_rzt2h_data },
+ { .compatible = "renesas,rzn1-rtc", .data = &rzn1_rtc_rzn1_data },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzn1_rtc_of_match);
static struct platform_driver rzn1_rtc_driver = {
.probe = rzn1_rtc_probe,
- .remove = rzn1_rtc_remove,
.driver = {
.name = "rzn1-rtc",
.of_match_table = rzn1_rtc_of_match,
@@ -512,6 +547,6 @@ static struct platform_driver rzn1_rtc_driver = {
module_platform_driver(rzn1_rtc_driver);
MODULE_AUTHOR("Michel Pollet <buserror@gmail.com>");
-MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com");
+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
MODULE_DESCRIPTION("RZ/N1 RTC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-s32g.c b/drivers/rtc/rtc-s32g.c
index 3a0818e972eb..86716192d10f 100644
--- a/drivers/rtc/rtc-s32g.c
+++ b/drivers/rtc/rtc-s32g.c
@@ -366,6 +366,7 @@ static const struct of_device_id rtc_dt_ids[] = {
{ .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data },
{ /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, rtc_dt_ids);
static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops,
s32g_rtc_suspend, s32g_rtc_resume);
diff --git a/drivers/rtc/rtc-spacemit-p1.c b/drivers/rtc/rtc-spacemit-p1.c
index 43ab62494bb4..1de7bd995d29 100644
--- a/drivers/rtc/rtc-spacemit-p1.c
+++ b/drivers/rtc/rtc-spacemit-p1.c
@@ -57,8 +57,9 @@ static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
u8 time[6];
int ret;
- if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN))
- return -EINVAL; /* RTC is disabled */
+ ret = regmap_test_bits(regmap, RTC_CTRL, RTC_EN);
+ if (ret <= 0)
+ return ret ?: -EINVAL; /* RTC is disabled or error */
ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
if (ret)
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index c6d4522411b3..ae79ddf24f37 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
@@ -212,11 +211,9 @@ static int st_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc->ioaddr))
return PTR_ERR(rtc->ioaddr);
- rtc->irq = irq_of_parse_and_map(np, 0);
- if (!rtc->irq) {
- dev_err(&pdev->dev, "IRQ missing or invalid\n");
- return -EINVAL;
- }
+ rtc->irq = platform_get_irq(pdev, 0);
+ if (rtc->irq < 0)
+ return rtc->irq;
ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
IRQF_NO_AUTOEN, pdev->name, rtc);
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index 2ae54804b87a..5bcb7536e973 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -334,10 +334,9 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
/* Getting the rtc info */
xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc");
- if (IS_ERR(xrtcdev->rtc_clk)) {
- if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER)
- dev_warn(&pdev->dev, "Device clock not found.\n");
- }
+ if (IS_ERR(xrtcdev->rtc_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(xrtcdev->rtc_clk),
+ "Failed to get rtc clock\n");
xrtcdev->freq = clk_get_rate(xrtcdev->rtc_clk);
if (!xrtcdev->freq) {
ret = of_property_read_u32(pdev->dev.of_node, "calibration",