aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-at91sam9.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-at91sam9.c')
-rw-r--r--drivers/rtc/rtc-at91sam9.c108
1 files changed, 36 insertions, 72 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 1d31c0ae6334..4daf3789b978 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -1,14 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0+
1/* 2/*
2 * "RTT as Real Time Clock" driver for AT91SAM9 SoC family 3 * "RTT as Real Time Clock" driver for AT91SAM9 SoC family
3 * 4 *
4 * (C) 2007 Michel Benoit 5 * (C) 2007 Michel Benoit
5 * 6 *
6 * Based on rtc-at91rm9200.c by Rick Bronson 7 * Based on rtc-at91rm9200.c by Rick Bronson
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */ 8 */
13 9
14#include <linux/clk.h> 10#include <linux/clk.h>
@@ -47,21 +43,21 @@
47 * registers available, likewise usable for more than "RTC" support. 43 * registers available, likewise usable for more than "RTC" support.
48 */ 44 */
49 45
50#define AT91_RTT_MR 0x00 /* Real-time Mode Register */ 46#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
51#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */ 47#define AT91_RTT_RTPRES (0xffff << 0) /* Timer Prescaler Value */
52#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ 48#define AT91_RTT_ALMIEN BIT(16) /* Alarm Interrupt Enable */
53#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ 49#define AT91_RTT_RTTINCIEN BIT(17) /* Increment Interrupt Enable */
54#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */ 50#define AT91_RTT_RTTRST BIT(18) /* Timer Restart */
55 51
56#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */ 52#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
57#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ 53#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
58 54
59#define AT91_RTT_VR 0x08 /* Real-time Value Register */ 55#define AT91_RTT_VR 0x08 /* Real-time Value Register */
60#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ 56#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
61 57
62#define AT91_RTT_SR 0x0c /* Real-time Status Register */ 58#define AT91_RTT_SR 0x0c /* Real-time Status Register */
63#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ 59#define AT91_RTT_ALMS BIT(0) /* Alarm Status */
64#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ 60#define AT91_RTT_RTTINC BIT(1) /* Timer Increment */
65 61
66/* 62/*
67 * We store ALARM_DISABLED in ALMV to record that no alarm is set. 63 * We store ALARM_DISABLED in ALMV to record that no alarm is set.
@@ -69,14 +65,13 @@
69 */ 65 */
70#define ALARM_DISABLED ((u32)~0) 66#define ALARM_DISABLED ((u32)~0)
71 67
72
73struct sam9_rtc { 68struct sam9_rtc {
74 void __iomem *rtt; 69 void __iomem *rtt;
75 struct rtc_device *rtcdev; 70 struct rtc_device *rtcdev;
76 u32 imr; 71 u32 imr;
77 struct regmap *gpbr; 72 struct regmap *gpbr;
78 unsigned int gpbr_offset; 73 unsigned int gpbr_offset;
79 int irq; 74 int irq;
80 struct clk *sclk; 75 struct clk *sclk;
81 bool suspended; 76 bool suspended;
82 unsigned long events; 77 unsigned long events;
@@ -122,7 +117,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
122 if (secs != secs2) 117 if (secs != secs2)
123 secs = rtt_readl(rtc, VR); 118 secs = rtt_readl(rtc, VR);
124 119
125 rtc_time_to_tm(offset + secs, tm); 120 rtc_time64_to_tm(offset + secs, tm);
126 121
127 dev_dbg(dev, "%s: %ptR\n", __func__, tm); 122 dev_dbg(dev, "%s: %ptR\n", __func__, tm);
128 123
@@ -135,15 +130,12 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
135static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) 130static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
136{ 131{
137 struct sam9_rtc *rtc = dev_get_drvdata(dev); 132 struct sam9_rtc *rtc = dev_get_drvdata(dev);
138 int err;
139 u32 offset, alarm, mr; 133 u32 offset, alarm, mr;
140 unsigned long secs; 134 unsigned long secs;
141 135
142 dev_dbg(dev, "%s: %ptR\n", __func__, tm); 136 dev_dbg(dev, "%s: %ptR\n", __func__, tm);
143 137
144 err = rtc_tm_to_time(tm, &secs); 138 secs = rtc_tm_to_time64(tm);
145 if (err != 0)
146 return err;
147 139
148 mr = rtt_readl(rtc, MR); 140 mr = rtt_readl(rtc, MR);
149 141
@@ -193,7 +185,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
193 185
194 memset(alrm, 0, sizeof(*alrm)); 186 memset(alrm, 0, sizeof(*alrm));
195 if (alarm != ALARM_DISABLED && offset != 0) { 187 if (alarm != ALARM_DISABLED && offset != 0) {
196 rtc_time_to_tm(offset + alarm, tm); 188 rtc_time64_to_tm(offset + alarm, tm);
197 189
198 dev_dbg(dev, "%s: %ptR\n", __func__, tm); 190 dev_dbg(dev, "%s: %ptR\n", __func__, tm);
199 191
@@ -211,11 +203,8 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
211 unsigned long secs; 203 unsigned long secs;
212 u32 offset; 204 u32 offset;
213 u32 mr; 205 u32 mr;
214 int err;
215 206
216 err = rtc_tm_to_time(tm, &secs); 207 secs = rtc_tm_to_time64(tm);
217 if (err != 0)
218 return err;
219 208
220 offset = gpbr_readl(rtc); 209 offset = gpbr_readl(rtc);
221 if (offset == 0) { 210 if (offset == 0) {
@@ -263,7 +252,7 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
263 u32 mr = rtt_readl(rtc, MR); 252 u32 mr = rtt_readl(rtc, MR);
264 253
265 seq_printf(seq, "update_IRQ\t: %s\n", 254 seq_printf(seq, "update_IRQ\t: %s\n",
266 (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); 255 (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no");
267 return 0; 256 return 0;
268} 257}
269 258
@@ -299,7 +288,7 @@ static void at91_rtc_flush_events(struct sam9_rtc *rtc)
299 rtc->events = 0; 288 rtc->events = 0;
300 289
301 pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, 290 pr_debug("%s: num=%ld, events=0x%02lx\n", __func__,
302 rtc->events >> 8, rtc->events & 0x000000FF); 291 rtc->events >> 8, rtc->events & 0x000000FF);
303} 292}
304 293
305/* 294/*
@@ -340,13 +329,6 @@ static const struct rtc_class_ops at91_rtc_ops = {
340 .alarm_irq_enable = at91_rtc_alarm_irq_enable, 329 .alarm_irq_enable = at91_rtc_alarm_irq_enable,
341}; 330};
342 331
343static const struct regmap_config gpbr_regmap_config = {
344 .name = "gpbr",
345 .reg_bits = 32,
346 .val_bits = 32,
347 .reg_stride = 4,
348};
349
350/* 332/*
351 * Initialize and install RTC driver 333 * Initialize and install RTC driver
352 */ 334 */
@@ -357,6 +339,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
357 int ret, irq; 339 int ret, irq;
358 u32 mr; 340 u32 mr;
359 unsigned int sclk_rate; 341 unsigned int sclk_rate;
342 struct of_phandle_args args;
360 343
361 irq = platform_get_irq(pdev, 0); 344 irq = platform_get_irq(pdev, 0);
362 if (irq < 0) { 345 if (irq < 0) {
@@ -382,34 +365,14 @@ static int at91_rtc_probe(struct platform_device *pdev)
382 if (IS_ERR(rtc->rtt)) 365 if (IS_ERR(rtc->rtt))
383 return PTR_ERR(rtc->rtt); 366 return PTR_ERR(rtc->rtt);
384 367
385 if (!pdev->dev.of_node) { 368 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
386 /* 369 "atmel,rtt-rtc-time-reg", 1, 0,
387 * TODO: Remove this code chunk when removing non DT board 370 &args);
388 * support. Remember to remove the gpbr_regmap_config 371 if (ret)
389 * variable too. 372 return ret;
390 */
391 void __iomem *gpbr;
392
393 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
394 gpbr = devm_ioremap_resource(&pdev->dev, r);
395 if (IS_ERR(gpbr))
396 return PTR_ERR(gpbr);
397
398 rtc->gpbr = regmap_init_mmio(NULL, gpbr,
399 &gpbr_regmap_config);
400 } else {
401 struct of_phandle_args args;
402
403 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
404 "atmel,rtt-rtc-time-reg", 1, 0,
405 &args);
406 if (ret)
407 return ret;
408
409 rtc->gpbr = syscon_node_to_regmap(args.np);
410 rtc->gpbr_offset = args.args[0];
411 }
412 373
374 rtc->gpbr = syscon_node_to_regmap(args.np);
375 rtc->gpbr_offset = args.args[0];
413 if (IS_ERR(rtc->gpbr)) { 376 if (IS_ERR(rtc->gpbr)) {
414 dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n"); 377 dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n");
415 return -ENOMEM; 378 return -ENOMEM;
@@ -444,13 +407,15 @@ static int at91_rtc_probe(struct platform_device *pdev)
444 mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); 407 mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
445 rtt_writel(rtc, MR, mr); 408 rtt_writel(rtc, MR, mr);
446 409
447 rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name, 410 rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
448 &at91_rtc_ops, THIS_MODULE);
449 if (IS_ERR(rtc->rtcdev)) { 411 if (IS_ERR(rtc->rtcdev)) {
450 ret = PTR_ERR(rtc->rtcdev); 412 ret = PTR_ERR(rtc->rtcdev);
451 goto err_clk; 413 goto err_clk;
452 } 414 }
453 415
416 rtc->rtcdev->ops = &at91_rtc_ops;
417 rtc->rtcdev->range_max = U32_MAX;
418
454 /* register irq handler after we know what name we'll use */ 419 /* register irq handler after we know what name we'll use */
455 ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, 420 ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt,
456 IRQF_SHARED | IRQF_COND_SUSPEND, 421 IRQF_SHARED | IRQF_COND_SUSPEND,
@@ -468,9 +433,9 @@ static int at91_rtc_probe(struct platform_device *pdev)
468 433
469 if (gpbr_readl(rtc) == 0) 434 if (gpbr_readl(rtc) == 0)
470 dev_warn(&pdev->dev, "%s: SET TIME!\n", 435 dev_warn(&pdev->dev, "%s: SET TIME!\n",
471 dev_name(&rtc->rtcdev->dev)); 436 dev_name(&rtc->rtcdev->dev));
472 437
473 return 0; 438 return rtc_register_device(rtc->rtcdev);
474 439
475err_clk: 440err_clk:
476 clk_disable_unprepare(rtc->sclk); 441 clk_disable_unprepare(rtc->sclk);
@@ -528,8 +493,9 @@ static int at91_rtc_suspend(struct device *dev)
528 /* don't let RTTINC cause wakeups */ 493 /* don't let RTTINC cause wakeups */
529 if (mr & AT91_RTT_RTTINCIEN) 494 if (mr & AT91_RTT_RTTINCIEN)
530 rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); 495 rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
531 } else 496 } else {
532 rtt_writel(rtc, MR, mr & ~rtc->imr); 497 rtt_writel(rtc, MR, mr & ~rtc->imr);
498 }
533 } 499 }
534 500
535 return 0; 501 return 0;
@@ -561,13 +527,11 @@ static int at91_rtc_resume(struct device *dev)
561 527
562static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); 528static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
563 529
564#ifdef CONFIG_OF
565static const struct of_device_id at91_rtc_dt_ids[] = { 530static const struct of_device_id at91_rtc_dt_ids[] = {
566 { .compatible = "atmel,at91sam9260-rtt" }, 531 { .compatible = "atmel,at91sam9260-rtt" },
567 { /* sentinel */ } 532 { /* sentinel */ }
568}; 533};
569MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); 534MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
570#endif
571 535
572static struct platform_driver at91_rtc_driver = { 536static struct platform_driver at91_rtc_driver = {
573 .probe = at91_rtc_probe, 537 .probe = at91_rtc_probe,