linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/12] rtc: handle alarms with a minute resolution
@ 2021-11-07 22:54 Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 02/12] rtc: s35390a: let the core handle the alarm resolution Alexandre Belloni
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Handle alarms with a minute resolution in the core. Until now drivers have
been open coding the seconds part removal and have been doing that wrongly.
Most of them are rounding up which means the allow the system to miss
deadlines. So, round down and let __rtc_set_alarm return immediately if the
time has already passed.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/interface.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index d005623e6eb3..d8e835798153 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -423,6 +423,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 	if (err)
 		return err;
 	now = rtc_tm_to_time64(&tm);
+
 	if (scheduled <= now)
 		return -ETIME;
 	/*
@@ -447,6 +448,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 
 int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 {
+	ktime_t alarm_time;
 	int err;
 
 	if (!rtc->ops)
@@ -468,7 +470,15 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 	if (rtc->aie_timer.enabled)
 		rtc_timer_remove(rtc, &rtc->aie_timer);
 
-	rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
+	alarm_time = rtc_tm_to_ktime(alarm->time);
+	/*
+	 * Round down so we never miss a deadline, checking for past deadline is
+	 * done in __rtc_set_alarm
+	 */
+	if (test_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features))
+		alarm_time = ktime_sub_ns(alarm_time, (u64)alarm->time.tm_sec * NSEC_PER_SEC);
+
+	rtc->aie_timer.node.expires = alarm_time;
 	rtc->aie_timer.period = 0;
 	if (alarm->enabled)
 		err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 02/12] rtc: s35390a: let the core handle the alarm resolution
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 03/12] rtc: rv3032: " Alexandre Belloni
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Tell the RTC core UIE are not supported because the resolution of the alarm
is a minute.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-s35390a.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index b5bdeda7d767..26278c770731 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -285,9 +285,6 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 		alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
 		alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
 
-	if (alm->time.tm_sec != 0)
-		dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n");
-
 	/* disable interrupt (which deasserts the irq line) */
 	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
 	if (err < 0)
@@ -491,8 +488,8 @@ static int s35390a_probe(struct i2c_client *client,
 	s35390a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	s35390a->rtc->range_max = RTC_TIMESTAMP_END_2099;
 
-	/* supports per-minute alarms only, therefore set uie_unsupported */
-	s35390a->rtc->uie_unsupported = 1;
+	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, s35390a->rtc->features);
+	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, s35390a->rtc->features );
 
 	if (status1 & S35390A_FLAG_INT2)
 		rtc_update_irq(s35390a->rtc, 1, RTC_AF);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 03/12] rtc: rv3032: let the core handle the alarm resolution
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 02/12] rtc: s35390a: let the core handle the alarm resolution Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 04/12] rtc: ab-eoz9: use RTC_FEATURE_UPDATE_INTERRUPT Alexandre Belloni
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Let the RTC core know the resolution of the alarm is a minute.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3032.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c
index a3c73179ecb1..c3bee305eacc 100644
--- a/drivers/rtc/rtc-rv3032.c
+++ b/drivers/rtc/rtc-rv3032.c
@@ -311,14 +311,6 @@ static int rv3032_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	u8 ctrl = 0;
 	int ret;
 
-	/* The alarm has no seconds, round up to nearest minute */
-	if (alrm->time.tm_sec) {
-		time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
-
-		alarm_time += 60 - alrm->time.tm_sec;
-		rtc_time64_to_tm(alarm_time, &alrm->time);
-	}
-
 	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
 				 RV3032_CTRL2_AIE | RV3032_CTRL2_UIE, 0);
 	if (ret)
@@ -958,6 +950,7 @@ static int rv3032_probe(struct i2c_client *client)
 	rv3032_trickle_charger_setup(&client->dev, rv3032);
 
 	set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3032->rtc->features);
+	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rv3032->rtc->features);
 
 	rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 04/12] rtc: ab-eoz9: use RTC_FEATURE_UPDATE_INTERRUPT
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 02/12] rtc: s35390a: let the core handle the alarm resolution Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 03/12] rtc: rv3032: " Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 05/12] rtc: ab-eoz9: support UIE when available Alexandre Belloni
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Switch from uie_unsupported to RTC_FEATURE_UPDATE_INTERRUPT

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ab-eoz9.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index a9b355510cd4..50ead6fce880 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -534,7 +534,7 @@ static int abeoz9_probe(struct i2c_client *client,
 	data->rtc->ops = &rtc_ops;
 	data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	data->rtc->range_max = RTC_TIMESTAMP_END_2099;
-	data->rtc->uie_unsupported = 1;
+	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, data->rtc->features);
 	clear_bit(RTC_FEATURE_ALARM, data->rtc->features);
 
 	if (client->irq > 0) {
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 05/12] rtc: ab-eoz9: support UIE when available
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (2 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 04/12] rtc: ab-eoz9: use RTC_FEATURE_UPDATE_INTERRUPT Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution Alexandre Belloni
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

The RTC actually supports UIE when an interrupt is available.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ab-eoz9.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index 50ead6fce880..e188ab517f1e 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -534,7 +534,6 @@ static int abeoz9_probe(struct i2c_client *client,
 	data->rtc->ops = &rtc_ops;
 	data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	data->rtc->range_max = RTC_TIMESTAMP_END_2099;
-	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, data->rtc->features);
 	clear_bit(RTC_FEATURE_ALARM, data->rtc->features);
 
 	if (client->irq > 0) {
@@ -546,6 +545,8 @@ static int abeoz9_probe(struct i2c_client *client,
 			dev_err(dev, "failed to request alarm irq\n");
 			return ret;
 		}
+	} else {
+		clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, data->rtc->features);
 	}
 
 	if (client->irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (3 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 05/12] rtc: ab-eoz9: support UIE when available Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-09 11:47   ` Linus Walleij
  2021-11-07 22:54 ` [PATCH 07/12] rtc: rx8025: switch to devm_rtc_allocate_device Alexandre Belloni
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Linus Walleij, Alexandre Belloni
  Cc: linux-rtc, linux-kernel, linux-arm-kernel

Tell the RTC core UIE are not supported because the resolution of the alarm
is a minute.

Note that this is in fact also fixing how the resolution is reported as the
previous test was simply ensuring the alarm was more than a minute in the
future while the register has a minute resolution.
This would be ok if the alarm was a countdown but ab8500_rtc_read_alarm
suggests otherwise and the AB8500 datasheet states that the RTC
documentation is not public.

Finally, the comment is wrong and what makes the UIE emulation work is
uie_unsupported being set.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-ab8500.c | 23 ++++-------------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index b40048871295..ea33e149d545 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -184,25 +184,9 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	int retval, i;
 	unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
-	unsigned long mins, secs = 0, cursec = 0;
-	struct rtc_time curtm;
+	unsigned long mins;
 
-	/* Get the number of seconds since 1970 */
-	secs = rtc_tm_to_time64(&alarm->time);
-
-	/*
-	 * Check whether alarm is set less than 1min.
-	 * Since our RTC doesn't support alarm resolution less than 1min,
-	 * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON
-	 */
-	ab8500_rtc_read_time(dev, &curtm); /* Read current time */
-	cursec = rtc_tm_to_time64(&curtm);
-	if ((secs - cursec) < 59) {
-		dev_dbg(dev, "Alarm less than 1 minute not supported\r\n");
-		return -EINVAL;
-	}
-
-	mins = secs / 60;
+	mins = (unsigned long)rtc_tm_to_time64(&alarm->time) / 60;
 
 	buf[2] = mins & 0xFF;
 	buf[1] = (mins >> 8) & 0xFF;
@@ -394,7 +378,8 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
 	dev_pm_set_wake_irq(&pdev->dev, irq);
 	platform_set_drvdata(pdev, rtc);
 
-	rtc->uie_unsupported = 1;
+	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features);
+	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
 
 	rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs
 	rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 07/12] rtc: rx8025: switch to devm_rtc_allocate_device
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (4 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 08/12] rtc: rx8025: let the core handle the alarm resolution Alexandre Belloni
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Switch to devm_rtc_allocate_device/devm_rtc_register_device, this allows
for further improvement of the driver.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index d38aaf08108c..617b044c66f0 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -559,12 +559,11 @@ static int rx8025_probe(struct i2c_client *client,
 	if (err)
 		return err;
 
-	rx8025->rtc = devm_rtc_device_register(&client->dev, client->name,
-					  &rx8025_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rx8025->rtc)) {
-		dev_err(&client->dev, "unable to register the class device\n");
+	rx8025->rtc = devm_rtc_allocate_device(&client->dev);
+	if (IS_ERR(rx8025->rtc))
 		return PTR_ERR(rx8025->rtc);
-	}
+
+	rx8025->rtc->ops = &rx8025_rtc_ops;
 
 	if (client->irq > 0) {
 		dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
@@ -583,6 +582,10 @@ static int rx8025_probe(struct i2c_client *client,
 	/* the rx8025 alarm only supports a minute accuracy */
 	rx8025->rtc->uie_unsupported = 1;
 
+	err = devm_rtc_register_device(rx8025->rtc);
+	if (err)
+		return err;
+
 	err = rx8025_sysfs_register(&client->dev);
 	return err;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 08/12] rtc: rx8025: let the core handle the alarm resolution
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (5 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 07/12] rtc: rx8025: switch to devm_rtc_allocate_device Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 09/12] rtc: rx8025: set range Alexandre Belloni
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Tell the RTC core UIE are not supported because the resolution of the alarm
is a minute.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index 617b044c66f0..6941e0518290 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -358,17 +358,6 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	if (client->irq <= 0)
 		return -EINVAL;
 
-	/*
-	 * Hardware alarm precision is 1 minute!
-	 * round up to nearest minute
-	 */
-	if (t->time.tm_sec) {
-		time64_t alarm_time = rtc_tm_to_time64(&t->time);
-
-		alarm_time += 60 - t->time.tm_sec;
-		rtc_time64_to_tm(alarm_time, &t->time);
-	}
-
 	ald[0] = bin2bcd(t->time.tm_min);
 	if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224)
 		ald[1] = bin2bcd(t->time.tm_hour);
@@ -579,8 +568,8 @@ static int rx8025_probe(struct i2c_client *client,
 
 	rx8025->rtc->max_user_freq = 1;
 
-	/* the rx8025 alarm only supports a minute accuracy */
-	rx8025->rtc->uie_unsupported = 1;
+	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rx8025->rtc->features);
+	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rx8025->rtc->features);
 
 	err = devm_rtc_register_device(rx8025->rtc);
 	if (err)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 09/12] rtc: rx8025: set range
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (6 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 08/12] rtc: rx8025: let the core handle the alarm resolution Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 10/12] rtc: rx8025: clear RTC_FEATURE_ALARM when alarm are not supported Alexandre Belloni
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Set the RTC range, it is a classic BCD RTC, with 00 being a leap
year. Let the core handle range checking.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index 6941e0518290..6002305efa2d 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -248,9 +248,6 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
 	u8 date[7];
 	int ret;
 
-	if ((dt->tm_year < 100) || (dt->tm_year > 199))
-		return -EINVAL;
-
 	/*
 	 * Here the read-only bits are written as "0".  I'm not sure if that
 	 * is sound.
@@ -553,6 +550,8 @@ static int rx8025_probe(struct i2c_client *client,
 		return PTR_ERR(rx8025->rtc);
 
 	rx8025->rtc->ops = &rx8025_rtc_ops;
+	rx8025->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
+	rx8025->rtc->range_max = RTC_TIMESTAMP_END_2099;
 
 	if (client->irq > 0) {
 		dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 10/12] rtc: rx8025: clear RTC_FEATURE_ALARM when alarm are not supported
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (7 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 09/12] rtc: rx8025: set range Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 11/12] rtc: rx8025: use rtc_add_group Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 12/12] rtc: rx8025: use .set_offset/.read_offset Alexandre Belloni
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Clear RTC_FEATURE_ALARM to signal alarms are not supported to the core
instead of checking client->irq.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index 6002305efa2d..fcfdefe94a7c 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -315,9 +315,6 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 	u8 ald[2];
 	int ctrl2, err;
 
-	if (client->irq <= 0)
-		return -EINVAL;
-
 	err = rx8025_read_regs(client, RX8025_REG_ALDMIN, 2, ald);
 	if (err)
 		return err;
@@ -352,9 +349,6 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	u8 ald[2];
 	int err;
 
-	if (client->irq <= 0)
-		return -EINVAL;
-
 	ald[0] = bin2bcd(t->time.tm_min);
 	if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224)
 		ald[1] = bin2bcd(t->time.tm_hour);
@@ -559,10 +553,8 @@ static int rx8025_probe(struct i2c_client *client,
 						rx8025_handle_irq,
 						IRQF_ONESHOT,
 						"rx8025", client);
-		if (err) {
-			dev_err(&client->dev, "unable to request IRQ, alarms disabled\n");
-			client->irq = 0;
-		}
+		if (err)
+			clear_bit(RTC_FEATURE_ALARM, rx8025->rtc->features);
 	}
 
 	rx8025->rtc->max_user_freq = 1;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 11/12] rtc: rx8025: use rtc_add_group
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (8 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 10/12] rtc: rx8025: clear RTC_FEATURE_ALARM when alarm are not supported Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  2021-11-07 22:54 ` [PATCH 12/12] rtc: rx8025: use .set_offset/.read_offset Alexandre Belloni
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

Remove open coded sysfs registration by using rtc_add_group.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 27 +++++++++------------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index fcfdefe94a7c..c5b3814f8c8e 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -502,15 +502,14 @@ static DEVICE_ATTR(clock_adjust_ppb, S_IRUGO | S_IWUSR,
 		   rx8025_sysfs_show_clock_adjust,
 		   rx8025_sysfs_store_clock_adjust);
 
-static int rx8025_sysfs_register(struct device *dev)
-{
-	return device_create_file(dev, &dev_attr_clock_adjust_ppb);
-}
+static struct attribute *rx8025_attrs[] = {
+	&dev_attr_clock_adjust_ppb.attr,
+	NULL
+};
 
-static void rx8025_sysfs_unregister(struct device *dev)
-{
-	device_remove_file(dev, &dev_attr_clock_adjust_ppb);
-}
+static const struct attribute_group rx8025_attr_group = {
+	.attrs	= rx8025_attrs,
+};
 
 static int rx8025_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
@@ -562,18 +561,11 @@ static int rx8025_probe(struct i2c_client *client,
 	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rx8025->rtc->features);
 	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rx8025->rtc->features);
 
-	err = devm_rtc_register_device(rx8025->rtc);
+	err = rtc_add_group(rx8025->rtc, &rx8025_attr_group);
 	if (err)
 		return err;
 
-	err = rx8025_sysfs_register(&client->dev);
-	return err;
-}
-
-static int rx8025_remove(struct i2c_client *client)
-{
-	rx8025_sysfs_unregister(&client->dev);
-	return 0;
+	return devm_rtc_register_device(rx8025->rtc);
 }
 
 static struct i2c_driver rx8025_driver = {
@@ -581,7 +573,6 @@ static struct i2c_driver rx8025_driver = {
 		.name = "rtc-rx8025",
 	},
 	.probe		= rx8025_probe,
-	.remove		= rx8025_remove,
 	.id_table	= rx8025_id,
 };
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 12/12] rtc: rx8025: use .set_offset/.read_offset
  2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
                   ` (9 preceding siblings ...)
  2021-11-07 22:54 ` [PATCH 11/12] rtc: rx8025: use rtc_add_group Alexandre Belloni
@ 2021-11-07 22:54 ` Alexandre Belloni
  10 siblings, 0 replies; 13+ messages in thread
From: Alexandre Belloni @ 2021-11-07 22:54 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni; +Cc: linux-rtc, linux-kernel

The driver has its own sysfs file to adjust the clock. Fortunately, it is
already in pbb, however, the sign it expects is the opposite of what the
RTC core does (which actually aligns with the RTC).

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rx8025.c | 73 ++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 37 deletions(-)

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index c5b3814f8c8e..5bfdd34a72ff 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -403,17 +403,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
 	return 0;
 }
 
-static const struct rtc_class_ops rx8025_rtc_ops = {
-	.read_time = rx8025_get_time,
-	.set_time = rx8025_set_time,
-	.read_alarm = rx8025_read_alarm,
-	.set_alarm = rx8025_set_alarm,
-	.alarm_irq_enable = rx8025_alarm_irq_enable,
-};
-
 /*
- * Clock precision adjustment support
- *
  * According to the RX8025 SA/NB application manual the frequency and
  * temperature characteristics can be approximated using the following
  * equation:
@@ -424,11 +414,8 @@ static const struct rtc_class_ops rx8025_rtc_ops = {
  *   a : Coefficient = (-35 +-5) * 10**-9
  *   ut: Ultimate temperature in degree = +25 +-5 degree
  *   t : Any temperature in degree
- *
- * Note that the clock adjustment in ppb must be entered (which is
- * the negative value of the deviation).
  */
-static int rx8025_get_clock_adjust(struct device *dev, int *adj)
+static int rx8025_read_offset(struct device *dev, long *offset)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	int digoff;
@@ -437,63 +424,75 @@ static int rx8025_get_clock_adjust(struct device *dev, int *adj)
 	if (digoff < 0)
 		return digoff;
 
-	*adj = digoff >= 64 ? digoff - 128 : digoff;
-	if (*adj > 0)
-		(*adj)--;
-	*adj *= -RX8025_ADJ_RESOLUTION;
+	*offset = digoff >= 64 ? digoff - 128 : digoff;
+	if (*offset > 0)
+		(*offset)--;
+	*offset *= RX8025_ADJ_RESOLUTION;
 
 	return 0;
 }
 
-static int rx8025_set_clock_adjust(struct device *dev, int adj)
+static int rx8025_set_offset(struct device *dev, long offset)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	u8 digoff;
 	int err;
 
-	adj /= -RX8025_ADJ_RESOLUTION;
-	if (adj > RX8025_ADJ_DATA_MAX)
-		adj = RX8025_ADJ_DATA_MAX;
-	else if (adj < RX8025_ADJ_DATA_MIN)
-		adj = RX8025_ADJ_DATA_MIN;
-	else if (adj > 0)
-		adj++;
-	else if (adj < 0)
-		adj += 128;
-	digoff = adj;
+	offset /= RX8025_ADJ_RESOLUTION;
+	if (offset > RX8025_ADJ_DATA_MAX)
+		offset = RX8025_ADJ_DATA_MAX;
+	else if (offset < RX8025_ADJ_DATA_MIN)
+		offset = RX8025_ADJ_DATA_MIN;
+	else if (offset > 0)
+		offset++;
+	else if (offset < 0)
+		offset += 128;
+	digoff = offset;
 
 	err = rx8025_write_reg(client, RX8025_REG_DIGOFF, digoff);
 	if (err)
 		return err;
 
-	dev_dbg(dev, "%s: write 0x%02x\n", __func__, digoff);
-
 	return 0;
 }
 
+static const struct rtc_class_ops rx8025_rtc_ops = {
+	.read_time = rx8025_get_time,
+	.set_time = rx8025_set_time,
+	.read_alarm = rx8025_read_alarm,
+	.set_alarm = rx8025_set_alarm,
+	.alarm_irq_enable = rx8025_alarm_irq_enable,
+	.read_offset = rx8025_read_offset,
+	.set_offset = rx8025_set_offset,
+};
+
 static ssize_t rx8025_sysfs_show_clock_adjust(struct device *dev,
 					      struct device_attribute *attr,
 					      char *buf)
 {
-	int err, adj;
+	long adj;
+	int err;
 
-	err = rx8025_get_clock_adjust(dev, &adj);
+	dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");
+	err = rx8025_read_offset(dev, &adj);
 	if (err)
 		return err;
 
-	return sprintf(buf, "%d\n", adj);
+	return sprintf(buf, "%ld\n", -adj);
 }
 
 static ssize_t rx8025_sysfs_store_clock_adjust(struct device *dev,
 					       struct device_attribute *attr,
 					       const char *buf, size_t count)
 {
-	int adj, err;
+	long adj;
+	int err;
 
-	if (sscanf(buf, "%i", &adj) != 1)
+	dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");
+	if (kstrtol(buf, 10, &adj) != 0)
 		return -EINVAL;
 
-	err = rx8025_set_clock_adjust(dev, adj);
+	err = rx8025_set_offset(dev, -adj);
 
 	return err ? err : count;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution
  2021-11-07 22:54 ` [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution Alexandre Belloni
@ 2021-11-09 11:47   ` Linus Walleij
  0 siblings, 0 replies; 13+ messages in thread
From: Linus Walleij @ 2021-11-09 11:47 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Alessandro Zummo, linux-rtc, linux-kernel, linux-arm-kernel

On Sun, Nov 7, 2021 at 11:55 PM Alexandre Belloni
<alexandre.belloni@bootlin.com> wrote:

> Tell the RTC core UIE are not supported because the resolution of the alarm
> is a minute.
>
> Note that this is in fact also fixing how the resolution is reported as the
> previous test was simply ensuring the alarm was more than a minute in the
> future while the register has a minute resolution.
> This would be ok if the alarm was a countdown but ab8500_rtc_read_alarm
> suggests otherwise and the AB8500 datasheet states that the RTC
> documentation is not public.
>
> Finally, the comment is wrong and what makes the UIE emulation work is
> uie_unsupported being set.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

I trust you on this one!
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-11-09 11:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-07 22:54 [PATCH 01/12] rtc: handle alarms with a minute resolution Alexandre Belloni
2021-11-07 22:54 ` [PATCH 02/12] rtc: s35390a: let the core handle the alarm resolution Alexandre Belloni
2021-11-07 22:54 ` [PATCH 03/12] rtc: rv3032: " Alexandre Belloni
2021-11-07 22:54 ` [PATCH 04/12] rtc: ab-eoz9: use RTC_FEATURE_UPDATE_INTERRUPT Alexandre Belloni
2021-11-07 22:54 ` [PATCH 05/12] rtc: ab-eoz9: support UIE when available Alexandre Belloni
2021-11-07 22:54 ` [PATCH 06/12] rtc: ab8500: let the core handle the alarm resolution Alexandre Belloni
2021-11-09 11:47   ` Linus Walleij
2021-11-07 22:54 ` [PATCH 07/12] rtc: rx8025: switch to devm_rtc_allocate_device Alexandre Belloni
2021-11-07 22:54 ` [PATCH 08/12] rtc: rx8025: let the core handle the alarm resolution Alexandre Belloni
2021-11-07 22:54 ` [PATCH 09/12] rtc: rx8025: set range Alexandre Belloni
2021-11-07 22:54 ` [PATCH 10/12] rtc: rx8025: clear RTC_FEATURE_ALARM when alarm are not supported Alexandre Belloni
2021-11-07 22:54 ` [PATCH 11/12] rtc: rx8025: use rtc_add_group Alexandre Belloni
2021-11-07 22:54 ` [PATCH 12/12] rtc: rx8025: use .set_offset/.read_offset Alexandre Belloni

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).