2019-12-29 20:53:08

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 1/9] rtc: at91rm9200: remove procfs information

The RTC procfs interface is deprecated and hasn't been used by userspace
for years.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 15 ---------------
1 file changed, 15 deletions(-)

diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 3b833e02a657..89d91ecd8ccf 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -254,20 +254,6 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)

return 0;
}
-/*
- * Provide additional RTC information in /proc/driver/rtc
- */
-static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
-{
- unsigned long imr = at91_rtc_read_imr();
-
- seq_printf(seq, "update_IRQ\t: %s\n",
- (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
- seq_printf(seq, "periodic_IRQ\t: %s\n",
- (imr & AT91_RTC_SECEV) ? "yes" : "no");
-
- return 0;
-}

/*
* IRQ handler for the RTC
@@ -337,7 +323,6 @@ static const struct rtc_class_ops at91_rtc_ops = {
.set_time = at91_rtc_settime,
.read_alarm = at91_rtc_readalarm,
.set_alarm = at91_rtc_setalarm,
- .proc = at91_rtc_proc,
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};

--
2.23.0


2019-12-29 20:53:23

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 2/9] dt-bindings: rtc: at91rm9200: convert bindings to json-schema

Convert Real Time Clock for Atmel/Microchip SoCs bindings documentation
to json-schema.

Cc: Rob Herring <[email protected]>
Signed-off-by: Alexandre Belloni <[email protected]>
---
.../bindings/rtc/atmel,at91rm9200-rtc.txt | 17 --------
.../bindings/rtc/atmel,at91rm9200-rtc.yaml | 42 +++++++++++++++++++
2 files changed, 42 insertions(+), 17 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
create mode 100644 Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml

diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
deleted file mode 100644
index 5d3791e789c6..000000000000
--- a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Atmel AT91RM9200 Real Time Clock
-
-Required properties:
-- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
-- reg: physical base address of the controller and length of memory mapped
- region.
-- interrupts: rtc alarm/event interrupt
-- clocks: phandle to input clock.
-
-Example:
-
-rtc@fffffe00 {
- compatible = "atmel,at91rm9200-rtc";
- reg = <0xfffffe00 0x100>;
- interrupts = <1 4 7>;
- clocks = <&clk32k>;
-};
diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
new file mode 100644
index 000000000000..55bd87e884d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/atmel,at91rm9200-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel AT91 RTC Device Tree Bindings
+
+allOf:
+ - $ref: "rtc.yaml#"
+
+maintainers:
+ - Alexandre Belloni <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - atmel,at91rm9200-rtc
+ - atmel,at91sam9x5-rtc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ rtc@fffffe00 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffe00 0x100>;
+ interrupts = <1 4 7>;
+ clocks = <&clk32k>;
+ };
+...
--
2.23.0

2019-12-29 20:53:23

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 5/9] rtc: at91rm9200: avoid time readout in at91_rtc_setalarm

The current rtc time is read out in at91_rtc_setalarm but it it immediately
overwritten by the alarm time. Remove the readout.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 997734ed9a5b..30b77e0f39ef 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -255,25 +255,17 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
*/
static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
- struct rtc_time tm;
-
- at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
-
- tm.tm_mon = alrm->time.tm_mon;
- tm.tm_mday = alrm->time.tm_mday;
- tm.tm_hour = alrm->time.tm_hour;
- tm.tm_min = alrm->time.tm_min;
- tm.tm_sec = alrm->time.tm_sec;
+ struct rtc_time tm = alrm->time;

at91_rtc_write_idr(AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_TIMALR,
- bin2bcd(tm.tm_sec) << 0
- | bin2bcd(tm.tm_min) << 8
- | bin2bcd(tm.tm_hour) << 16
+ bin2bcd(alrm->time.tm_sec) << 0
+ | bin2bcd(alrm->time.tm_min) << 8
+ | bin2bcd(alrm->time.tm_hour) << 16
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_rtc_write(AT91_RTC_CALALR,
- bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
- | bin2bcd(tm.tm_mday) << 24
+ bin2bcd(alrm->time.tm_mon + 1) << 16 /* tm_mon starts at zero */
+ | bin2bcd(alrm->time.tm_mday) << 24
| AT91_RTC_DATEEN | AT91_RTC_MTHEN);

if (alrm->enabled) {
--
2.23.0

2019-12-29 20:53:26

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 6/9] rtc: at91rm9200: use FIELD_PREP/FIELD_GET

Use FIELD_PREP and FIELD_GET instead of hardcoding already defined values.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 42 +++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 30b77e0f39ef..5e811e04cb21 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -14,6 +14,7 @@
*/

#include <linux/bcd.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
@@ -161,20 +162,20 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
} while ((time != at91_rtc_read(timereg)) ||
(date != at91_rtc_read(calreg)));

- tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
- tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
- tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
+ tm->tm_sec = bcd2bin(FIELD_GET(AT91_RTC_SEC, time));
+ tm->tm_min = bcd2bin(FIELD_GET(AT91_RTC_MIN, time));
+ tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time));

/*
* The Calendar Alarm register does not have a field for
* the year - so these will return an invalid value.
*/
tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */
- tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */
+ tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */

- tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
- tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
- tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
+ tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1; /* day of the week [0-6], Sunday=0 */
+ tm->tm_mon = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1;
+ tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date));
}

/*
@@ -211,16 +212,17 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
at91_rtc_write_idr(AT91_RTC_ACKUPD);

at91_rtc_write(AT91_RTC_TIMR,
- bin2bcd(tm->tm_sec) << 0
- | bin2bcd(tm->tm_min) << 8
- | bin2bcd(tm->tm_hour) << 16);
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec))
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min))
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour)));

at91_rtc_write(AT91_RTC_CALR,
- bin2bcd((tm->tm_year + 1900) / 100) /* century */
- | bin2bcd(tm->tm_year % 100) << 8 /* year */
- | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
- | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
- | bin2bcd(tm->tm_mday) << 24);
+ FIELD_PREP(AT91_RTC_CENT,
+ bin2bcd((tm->tm_year + 1900) / 100))
+ | FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100))
+ | FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1))
+ | FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1))
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday)));

/* Restart Time/Calendar */
cr = at91_rtc_read(AT91_RTC_CR);
@@ -259,13 +261,13 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)

at91_rtc_write_idr(AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_TIMALR,
- bin2bcd(alrm->time.tm_sec) << 0
- | bin2bcd(alrm->time.tm_min) << 8
- | bin2bcd(alrm->time.tm_hour) << 16
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec))
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min))
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour))
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_rtc_write(AT91_RTC_CALALR,
- bin2bcd(alrm->time.tm_mon + 1) << 16 /* tm_mon starts at zero */
- | bin2bcd(alrm->time.tm_mday) << 24
+ FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1))
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday))
| AT91_RTC_DATEEN | AT91_RTC_MTHEN);

if (alrm->enabled) {
--
2.23.0

2019-12-29 20:53:29

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 4/9] rtc: at91rm9200: move register definitions to C file

The header was simply moved from the arm mach folder to drivers/rtc but
there is not point in having it separated from the driver.

Also remove unused bit definitions and use BIT and GENMASK.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 46 ++++++++++++++++++++++-
drivers/rtc/rtc-at91rm9200.h | 71 ------------------------------------
2 files changed, 45 insertions(+), 72 deletions(-)
delete mode 100644 drivers/rtc/rtc-at91rm9200.h

diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index bda8e009076f..997734ed9a5b 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -30,7 +30,51 @@
#include <linux/time.h>
#include <linux/uaccess.h>

-#include "rtc-at91rm9200.h"
+#define AT91_RTC_CR 0x00 /* Control Register */
+#define AT91_RTC_UPDTIM BIT(0) /* Update Request Time Register */
+#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */
+
+#define AT91_RTC_MR 0x04 /* Mode Register */
+
+#define AT91_RTC_TIMR 0x08 /* Time Register */
+#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
+#define AT91_RTC_MIN GENMASK(14, 8) /* Current Minute */
+#define AT91_RTC_HOUR GENMASK(21, 16) /* Current Hour */
+#define AT91_RTC_AMPM BIT(22) /* Ante Meridiem Post Meridiem Indicator */
+
+#define AT91_RTC_CALR 0x0c /* Calendar Register */
+#define AT91_RTC_CENT GENMASK(6, 0) /* Current Century */
+#define AT91_RTC_YEAR GENMASK(15, 8) /* Current Year */
+#define AT91_RTC_MONTH GENMASK(20, 16) /* Current Month */
+#define AT91_RTC_DAY GENMASK(23, 21) /* Current Day */
+#define AT91_RTC_DATE GENMASK(29, 24) /* Current Date */
+
+#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
+#define AT91_RTC_SECEN BIT(7) /* Second Alarm Enable */
+#define AT91_RTC_MINEN BIT(15) /* Minute Alarm Enable */
+#define AT91_RTC_HOUREN BIT(23) /* Hour Alarm Enable */
+
+#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
+#define AT91_RTC_MTHEN BIT(23) /* Month Alarm Enable */
+#define AT91_RTC_DATEEN BIT(31) /* Date Alarm Enable */
+
+#define AT91_RTC_SR 0x18 /* Status Register */
+#define AT91_RTC_ACKUPD BIT(0) /* Acknowledge for Update */
+#define AT91_RTC_ALARM BIT(1) /* Alarm Flag */
+#define AT91_RTC_SECEV BIT(2) /* Second Event */
+#define AT91_RTC_TIMEV BIT(3) /* Time Event */
+#define AT91_RTC_CALEV BIT(4) /* Calendar Event */
+
+#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
+#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
+#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
+#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
+
+#define AT91_RTC_VER 0x2c /* Valid Entry Register */
+#define AT91_RTC_NVTIM BIT(0) /* Non valid Time */
+#define AT91_RTC_NVCAL BIT(1) /* Non valid Calendar */
+#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
+#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */

#define at91_rtc_read(field) \
readl_relaxed(at91_rtc_regs + field)
diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h
deleted file mode 100644
index 8be5289da8e2..000000000000
--- a/drivers/rtc/rtc-at91rm9200.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-at91/include/mach/at91_rtc.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Real Time Clock (RTC) - System peripheral registers.
- * Based on AT91RM9200 datasheet revision E.
- */
-
-#ifndef AT91_RTC_H
-#define AT91_RTC_H
-
-#define AT91_RTC_CR 0x00 /* Control Register */
-#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
-#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
-#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
-#define AT91_RTC_TIMEVSEL_MINUTE (0 << 8)
-#define AT91_RTC_TIMEVSEL_HOUR (1 << 8)
-#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8)
-#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8)
-#define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */
-#define AT91_RTC_CALEVSEL_WEEK (0 << 16)
-#define AT91_RTC_CALEVSEL_MONTH (1 << 16)
-#define AT91_RTC_CALEVSEL_YEAR (2 << 16)
-
-#define AT91_RTC_MR 0x04 /* Mode Register */
-#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
-
-#define AT91_RTC_TIMR 0x08 /* Time Register */
-#define AT91_RTC_SEC (0x7f << 0) /* Current Second */
-#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
-#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
-#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
-
-#define AT91_RTC_CALR 0x0c /* Calendar Register */
-#define AT91_RTC_CENT (0x7f << 0) /* Current Century */
-#define AT91_RTC_YEAR (0xff << 8) /* Current Year */
-#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
-#define AT91_RTC_DAY (7 << 21) /* Current Day */
-#define AT91_RTC_DATE (0x3f << 24) /* Current Date */
-
-#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
-#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
-#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
-#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
-
-#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
-#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
-#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
-
-#define AT91_RTC_SR 0x18 /* Status Register */
-#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
-#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
-#define AT91_RTC_SECEV (1 << 2) /* Second Event */
-#define AT91_RTC_TIMEV (1 << 3) /* Time Event */
-#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
-
-#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
-#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
-#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
-#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
-
-#define AT91_RTC_VER 0x2c /* Valid Entry Register */
-#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
-#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
-#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
-#define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */
-
-#endif
--
2.23.0

2019-12-29 20:53:36

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 7/9] rtc: at91rm9200: add correction support

The sama5d4 and sama5d2 RTCs are able to correct for imprecise crystals, up
to 1953 ppm.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 95 ++++++++++++++++++++++++++++++++++--
1 file changed, 91 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 5e811e04cb21..fe4823e1fd60 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -36,6 +36,10 @@
#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */

#define AT91_RTC_MR 0x04 /* Mode Register */
+#define AT91_RTC_HRMOD BIT(0) /* 12/24 hour mode */
+#define AT91_RTC_NEGPPM BIT(4) /* Negative PPM correction */
+#define AT91_RTC_CORRECTION GENMASK(14, 8) /* Slow clock correction */
+#define AT91_RTC_HIGHPPM BIT(15) /* High PPM correction */

#define AT91_RTC_TIMR 0x08 /* Time Register */
#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
@@ -77,6 +81,9 @@
#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */

+#define AT91_RTC_CORR_STEP 1526
+#define AT91_RTC_CORR_STEP_HIGH 30516
+
#define at91_rtc_read(field) \
readl_relaxed(at91_rtc_regs + field)
#define at91_rtc_write(field, val) \
@@ -84,6 +91,7 @@

struct at91_rtc_config {
bool use_shadow_imr;
+ bool has_correction;
};

static const struct at91_rtc_config *at91_rtc_config;
@@ -293,6 +301,66 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}

+static int at91_rtc_readoffset(struct device *dev, long *offset)
+{
+ u32 mr = at91_rtc_read(AT91_RTC_MR);
+ long val = FIELD_GET(AT91_RTC_CORRECTION, mr);
+
+ if (!val) {
+ *offset = 0;
+ return 0;
+ }
+
+ val++;
+
+ if (mr & AT91_RTC_NEGPPM)
+ val = -val;
+
+ if (mr & AT91_RTC_HIGHPPM)
+ *offset = val * AT91_RTC_CORR_STEP_HIGH;
+ else
+ *offset = val * AT91_RTC_CORR_STEP;
+
+ return 0;
+}
+
+static int at91_rtc_setoffset(struct device *dev, long offset)
+{
+ long mode0, mode1, error0, error1;
+ u32 mr;
+
+
+ if (offset > AT91_RTC_CORR_STEP_HIGH * 128)
+ return -ERANGE;
+ if (offset < AT91_RTC_CORR_STEP_HIGH * -128)
+ return -ERANGE;
+
+ mr = at91_rtc_read(AT91_RTC_MR);
+ mr &= ~(AT91_RTC_NEGPPM | AT91_RTC_CORRECTION | AT91_RTC_HIGHPPM);
+
+ if (offset < 0) {
+ mr |= AT91_RTC_NEGPPM;
+ offset = -offset;
+ }
+
+ mode0 = DIV_ROUND_CLOSEST(offset, AT91_RTC_CORR_STEP);
+ mode1 = DIV_ROUND_CLOSEST(offset, AT91_RTC_CORR_STEP_HIGH);
+
+ error0 = abs(offset - (mode0 * AT91_RTC_CORR_STEP));
+ error1 = abs(offset - (mode1 * AT91_RTC_CORR_STEP_HIGH));
+
+ if (mode0 > 128 || error0 > error1) {
+ mr |= AT91_RTC_HIGHPPM;
+ mr |= FIELD_PREP(AT91_RTC_CORRECTION, mode1 - 1);
+ } else {
+ mr |= FIELD_PREP(AT91_RTC_CORRECTION, mode0 - 1);
+ }
+
+ at91_rtc_write(AT91_RTC_MR, mr);
+
+ return 0;
+}
+
/*
* IRQ handler for the RTC
*/
@@ -343,6 +411,10 @@ static const struct at91_rtc_config at91sam9x5_config = {
.use_shadow_imr = true,
};

+static const struct at91_rtc_config sama5d4_config = {
+ .has_correction = true,
+};
+
static const struct of_device_id at91_rtc_dt_ids[] = {
{
.compatible = "atmel,at91rm9200-rtc",
@@ -352,10 +424,10 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
.data = &at91sam9x5_config,
}, {
.compatible = "atmel,sama5d4-rtc",
- .data = &at91rm9200_config,
+ .data = &sama5d4_config,
}, {
.compatible = "atmel,sama5d2-rtc",
- .data = &at91rm9200_config,
+ .data = &sama5d4_config,
}, {
/* sentinel */
}
@@ -370,6 +442,16 @@ static const struct rtc_class_ops at91_rtc_ops = {
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};

+static const struct rtc_class_ops sama5d4_rtc_ops = {
+ .read_time = at91_rtc_readtime,
+ .set_time = at91_rtc_settime,
+ .read_alarm = at91_rtc_readalarm,
+ .set_alarm = at91_rtc_setalarm,
+ .alarm_irq_enable = at91_rtc_alarm_irq_enable,
+ .set_offset = at91_rtc_setoffset,
+ .read_offset = at91_rtc_readoffset,
+};
+
/*
* Initialize and install RTC driver
*/
@@ -416,7 +498,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
}

at91_rtc_write(AT91_RTC_CR, 0);
- at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */
+ at91_rtc_write(AT91_RTC_MR,
+ at91_rtc_read(AT91_RTC_MR) & ~AT91_RTC_HRMOD);

/* Disable all interrupts */
at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
@@ -437,7 +520,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (!device_can_wakeup(&pdev->dev))
device_init_wakeup(&pdev->dev, 1);

- rtc->ops = &at91_rtc_ops;
+ if (at91_rtc_config->has_correction)
+ rtc->ops = &sama5d4_rtc_ops;
+ else
+ rtc->ops = &at91_rtc_ops;
+
rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(rtc);
--
2.23.0

2019-12-29 20:53:47

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 8/9] ARM: dts: at91: sama5d2: use correct rtc compatible

Use the sama5d2 specific compatible string for the RTC.

Signed-off-by: Alexandre Belloni <[email protected]>
---
arch/arm/boot/dts/sama5d2.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 565204816e34..4e125348fd76 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -690,7 +690,7 @@
};

rtc: rtc@f80480b0 {
- compatible = "atmel,at91rm9200-rtc";
+ compatible = "atmel,sama5d2-rtc";
reg = <0xf80480b0 0x30>;
interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k>;
--
2.23.0

2019-12-29 20:54:12

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 3/9] rtc: at91rm9200: add sama5d4 and sama5d2 compatibles

Both the sama5d4 and sama5d2 RTCs have more features than the previous
RTCs, add a compatible string for them.

Signed-off-by: Alexandre Belloni <[email protected]>
---
.../devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml | 2 ++
drivers/rtc/rtc-at91rm9200.c | 6 ++++++
2 files changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
index 55bd87e884d3..0c642e1c855b 100644
--- a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
@@ -17,6 +17,8 @@ properties:
enum:
- atmel,at91rm9200-rtc
- atmel,at91sam9x5-rtc
+ - atmel,sama5d4-rtc
+ - atmel,sama5d2-rtc

reg:
maxItems: 1
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 89d91ecd8ccf..bda8e009076f 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -312,6 +312,12 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
}, {
.compatible = "atmel,at91sam9x5-rtc",
.data = &at91sam9x5_config,
+ }, {
+ .compatible = "atmel,sama5d4-rtc",
+ .data = &at91rm9200_config,
+ }, {
+ .compatible = "atmel,sama5d2-rtc",
+ .data = &at91rm9200_config,
}, {
/* sentinel */
}
--
2.23.0

2019-12-29 20:54:33

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 9/9] ARM: dts: at91: sama5d4: use correct rtc compatible

Use the sama5d4 specific compatible string for the RTC.

Signed-off-by: Alexandre Belloni <[email protected]>
---
arch/arm/boot/dts/sama5d4.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 6ab27a7b388d..e9a8f82a6eda 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -884,7 +884,7 @@
};

rtc@fc0686b0 {
- compatible = "atmel,at91rm9200-rtc";
+ compatible = "atmel,sama5d4-rtc";
reg = <0xfc0686b0 0x30>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k>;
--
2.23.0

2020-01-28 14:34:40

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 2/9] dt-bindings: rtc: at91rm9200: convert bindings to json-schema

On Sun, Dec 29, 2019 at 2:45 PM Alexandre Belloni
<[email protected]> wrote:
>
> Convert Real Time Clock for Atmel/Microchip SoCs bindings documentation
> to json-schema.
>
> Cc: Rob Herring <[email protected]>
> Signed-off-by: Alexandre Belloni <[email protected]>
> ---
> .../bindings/rtc/atmel,at91rm9200-rtc.txt | 17 --------
> .../bindings/rtc/atmel,at91rm9200-rtc.yaml | 42 +++++++++++++++++++
> 2 files changed, 42 insertions(+), 17 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
> create mode 100644 Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
>
> diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
> deleted file mode 100644
> index 5d3791e789c6..000000000000
> --- a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -Atmel AT91RM9200 Real Time Clock
> -
> -Required properties:
> -- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
> -- reg: physical base address of the controller and length of memory mapped
> - region.
> -- interrupts: rtc alarm/event interrupt
> -- clocks: phandle to input clock.
> -
> -Example:
> -
> -rtc@fffffe00 {
> - compatible = "atmel,at91rm9200-rtc";
> - reg = <0xfffffe00 0x100>;
> - interrupts = <1 4 7>;
> - clocks = <&clk32k>;
> -};
> diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
> new file mode 100644
> index 000000000000..55bd87e884d3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
> @@ -0,0 +1,42 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/rtc/atmel,at91rm9200-rtc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel AT91 RTC Device Tree Bindings
> +
> +allOf:
> + - $ref: "rtc.yaml#"
> +
> +maintainers:
> + - Alexandre Belloni <[email protected]>
> +
> +properties:
> + compatible:
> + enum:
> + - atmel,at91rm9200-rtc
> + - atmel,at91sam9x5-rtc
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + rtc@fffffe00 {
> + compatible = "atmel,at91rm9200-rtc";
> + reg = <0xfffffe00 0x100>;
> + interrupts = <1 4 7>;
> + clocks = <&clk32k>;

clocks is not documented.

Looks like this landed in linux-next now and breaks 'make dt_binding_check':

/builds/robherring/linux-dt-bindings/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.example.dt.yaml:
rtc@fffffe00: 'clocks' does not match any of the regexes:
'pinctrl-[0-9]+'

Rob