hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/rtc/rtc-at91rm9200.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Real Time Clock interface for Linux on Atmel AT91RM9200
34 *
....@@ -10,15 +11,10 @@
1011 *
1112 * Based on sa1100-rtc.c by Nils Faerber
1213 * Based on rtc.c by Paul Gortmaker
13
- *
14
- * This program is free software; you can redistribute it and/or
15
- * modify it under the terms of the GNU General Public License
16
- * as published by the Free Software Foundation; either version
17
- * 2 of the License, or (at your option) any later version.
18
- *
1914 */
2015
2116 #include <linux/bcd.h>
17
+#include <linux/bitfield.h>
2218 #include <linux/clk.h>
2319 #include <linux/completion.h>
2420 #include <linux/interrupt.h>
....@@ -35,7 +31,51 @@
3531 #include <linux/time.h>
3632 #include <linux/uaccess.h>
3733
38
-#include "rtc-at91rm9200.h"
34
+#define AT91_RTC_CR 0x00 /* Control Register */
35
+#define AT91_RTC_UPDTIM BIT(0) /* Update Request Time Register */
36
+#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */
37
+
38
+#define AT91_RTC_MR 0x04 /* Mode Register */
39
+
40
+#define AT91_RTC_TIMR 0x08 /* Time Register */
41
+#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
42
+#define AT91_RTC_MIN GENMASK(14, 8) /* Current Minute */
43
+#define AT91_RTC_HOUR GENMASK(21, 16) /* Current Hour */
44
+#define AT91_RTC_AMPM BIT(22) /* Ante Meridiem Post Meridiem Indicator */
45
+
46
+#define AT91_RTC_CALR 0x0c /* Calendar Register */
47
+#define AT91_RTC_CENT GENMASK(6, 0) /* Current Century */
48
+#define AT91_RTC_YEAR GENMASK(15, 8) /* Current Year */
49
+#define AT91_RTC_MONTH GENMASK(20, 16) /* Current Month */
50
+#define AT91_RTC_DAY GENMASK(23, 21) /* Current Day */
51
+#define AT91_RTC_DATE GENMASK(29, 24) /* Current Date */
52
+
53
+#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
54
+#define AT91_RTC_SECEN BIT(7) /* Second Alarm Enable */
55
+#define AT91_RTC_MINEN BIT(15) /* Minute Alarm Enable */
56
+#define AT91_RTC_HOUREN BIT(23) /* Hour Alarm Enable */
57
+
58
+#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
59
+#define AT91_RTC_MTHEN BIT(23) /* Month Alarm Enable */
60
+#define AT91_RTC_DATEEN BIT(31) /* Date Alarm Enable */
61
+
62
+#define AT91_RTC_SR 0x18 /* Status Register */
63
+#define AT91_RTC_ACKUPD BIT(0) /* Acknowledge for Update */
64
+#define AT91_RTC_ALARM BIT(1) /* Alarm Flag */
65
+#define AT91_RTC_SECEV BIT(2) /* Second Event */
66
+#define AT91_RTC_TIMEV BIT(3) /* Time Event */
67
+#define AT91_RTC_CALEV BIT(4) /* Calendar Event */
68
+
69
+#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
70
+#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
71
+#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
72
+#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
73
+
74
+#define AT91_RTC_VER 0x2c /* Valid Entry Register */
75
+#define AT91_RTC_NVTIM BIT(0) /* Non valid Time */
76
+#define AT91_RTC_NVCAL BIT(1) /* Non valid Calendar */
77
+#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
78
+#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */
3979
4080 #define at91_rtc_read(field) \
4181 readl_relaxed(at91_rtc_regs + field)
....@@ -122,20 +162,20 @@
122162 } while ((time != at91_rtc_read(timereg)) ||
123163 (date != at91_rtc_read(calreg)));
124164
125
- tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
126
- tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
127
- tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
165
+ tm->tm_sec = bcd2bin(FIELD_GET(AT91_RTC_SEC, time));
166
+ tm->tm_min = bcd2bin(FIELD_GET(AT91_RTC_MIN, time));
167
+ tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time));
128168
129169 /*
130170 * The Calendar Alarm register does not have a field for
131171 * the year - so these will return an invalid value.
132172 */
133173 tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */
134
- tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */
174
+ tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */
135175
136
- tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
137
- tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
138
- tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
176
+ tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1; /* day of the week [0-6], Sunday=0 */
177
+ tm->tm_mon = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1;
178
+ tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date));
139179 }
140180
141181 /*
....@@ -147,9 +187,7 @@
147187 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
148188 tm->tm_year = tm->tm_year - 1900;
149189
150
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
151
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
152
- tm->tm_hour, tm->tm_min, tm->tm_sec);
190
+ dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
153191
154192 return 0;
155193 }
....@@ -161,9 +199,7 @@
161199 {
162200 unsigned long cr;
163201
164
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
165
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
166
- tm->tm_hour, tm->tm_min, tm->tm_sec);
202
+ dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
167203
168204 wait_for_completion(&at91_rtc_upd_rdy);
169205
....@@ -176,16 +212,17 @@
176212 at91_rtc_write_idr(AT91_RTC_ACKUPD);
177213
178214 at91_rtc_write(AT91_RTC_TIMR,
179
- bin2bcd(tm->tm_sec) << 0
180
- | bin2bcd(tm->tm_min) << 8
181
- | bin2bcd(tm->tm_hour) << 16);
215
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec))
216
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min))
217
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour)));
182218
183219 at91_rtc_write(AT91_RTC_CALR,
184
- bin2bcd((tm->tm_year + 1900) / 100) /* century */
185
- | bin2bcd(tm->tm_year % 100) << 8 /* year */
186
- | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
187
- | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
188
- | bin2bcd(tm->tm_mday) << 24);
220
+ FIELD_PREP(AT91_RTC_CENT,
221
+ bin2bcd((tm->tm_year + 1900) / 100))
222
+ | FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100))
223
+ | FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1))
224
+ | FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1))
225
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday)));
189226
190227 /* Restart Time/Calendar */
191228 cr = at91_rtc_read(AT91_RTC_CR);
....@@ -209,8 +246,7 @@
209246 alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
210247 ? 1 : 0;
211248
212
- dev_dbg(dev, "%s(): %02d-%02d %02d:%02d:%02d %sabled\n", __func__,
213
- tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
249
+ dev_dbg(dev, "%s(): %ptR %sabled\n", __func__, tm,
214250 alrm->enabled ? "en" : "dis");
215251
216252 return 0;
....@@ -221,25 +257,17 @@
221257 */
222258 static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
223259 {
224
- struct rtc_time tm;
225
-
226
- at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
227
-
228
- tm.tm_mon = alrm->time.tm_mon;
229
- tm.tm_mday = alrm->time.tm_mday;
230
- tm.tm_hour = alrm->time.tm_hour;
231
- tm.tm_min = alrm->time.tm_min;
232
- tm.tm_sec = alrm->time.tm_sec;
260
+ struct rtc_time tm = alrm->time;
233261
234262 at91_rtc_write_idr(AT91_RTC_ALARM);
235263 at91_rtc_write(AT91_RTC_TIMALR,
236
- bin2bcd(tm.tm_sec) << 0
237
- | bin2bcd(tm.tm_min) << 8
238
- | bin2bcd(tm.tm_hour) << 16
264
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec))
265
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min))
266
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour))
239267 | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
240268 at91_rtc_write(AT91_RTC_CALALR,
241
- bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
242
- | bin2bcd(tm.tm_mday) << 24
269
+ FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1))
270
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday))
243271 | AT91_RTC_DATEEN | AT91_RTC_MTHEN);
244272
245273 if (alrm->enabled) {
....@@ -247,9 +275,7 @@
247275 at91_rtc_write_ier(AT91_RTC_ALARM);
248276 }
249277
250
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
251
- tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
252
- tm.tm_min, tm.tm_sec);
278
+ dev_dbg(dev, "%s(): %ptR\n", __func__, &tm);
253279
254280 return 0;
255281 }
....@@ -263,20 +289,6 @@
263289 at91_rtc_write_ier(AT91_RTC_ALARM);
264290 } else
265291 at91_rtc_write_idr(AT91_RTC_ALARM);
266
-
267
- return 0;
268
-}
269
-/*
270
- * Provide additional RTC information in /proc/driver/rtc
271
- */
272
-static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
273
-{
274
- unsigned long imr = at91_rtc_read_imr();
275
-
276
- seq_printf(seq, "update_IRQ\t: %s\n",
277
- (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
278
- seq_printf(seq, "periodic_IRQ\t: %s\n",
279
- (imr & AT91_RTC_SECEV) ? "yes" : "no");
280292
281293 return 0;
282294 }
....@@ -331,7 +343,6 @@
331343 .use_shadow_imr = true,
332344 };
333345
334
-#ifdef CONFIG_OF
335346 static const struct of_device_id at91_rtc_dt_ids[] = {
336347 {
337348 .compatible = "atmel,at91rm9200-rtc",
....@@ -340,33 +351,22 @@
340351 .compatible = "atmel,at91sam9x5-rtc",
341352 .data = &at91sam9x5_config,
342353 }, {
354
+ .compatible = "atmel,sama5d4-rtc",
355
+ .data = &at91rm9200_config,
356
+ }, {
357
+ .compatible = "atmel,sama5d2-rtc",
358
+ .data = &at91rm9200_config,
359
+ }, {
343360 /* sentinel */
344361 }
345362 };
346363 MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
347
-#endif
348
-
349
-static const struct at91_rtc_config *
350
-at91_rtc_get_config(struct platform_device *pdev)
351
-{
352
- const struct of_device_id *match;
353
-
354
- if (pdev->dev.of_node) {
355
- match = of_match_node(at91_rtc_dt_ids, pdev->dev.of_node);
356
- if (!match)
357
- return NULL;
358
- return (const struct at91_rtc_config *)match->data;
359
- }
360
-
361
- return &at91rm9200_config;
362
-}
363364
364365 static const struct rtc_class_ops at91_rtc_ops = {
365366 .read_time = at91_rtc_readtime,
366367 .set_time = at91_rtc_settime,
367368 .read_alarm = at91_rtc_readalarm,
368369 .set_alarm = at91_rtc_setalarm,
369
- .proc = at91_rtc_proc,
370370 .alarm_irq_enable = at91_rtc_alarm_irq_enable,
371371 };
372372
....@@ -379,7 +379,7 @@
379379 struct resource *regs;
380380 int ret = 0;
381381
382
- at91_rtc_config = at91_rtc_get_config(pdev);
382
+ at91_rtc_config = of_device_get_match_data(&pdev->dev);
383383 if (!at91_rtc_config)
384384 return -ENODEV;
385385
....@@ -390,10 +390,8 @@
390390 }
391391
392392 irq = platform_get_irq(pdev, 0);
393
- if (irq < 0) {
394
- dev_err(&pdev->dev, "no irq resource defined\n");
393
+ if (irq < 0)
395394 return -ENXIO;
396
- }
397395
398396 at91_rtc_regs = devm_ioremap(&pdev->dev, regs->start,
399397 resource_size(regs));