aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-at91sam9.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:46:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:46:33 -0400
commit8e4ff713ce313dcabbb60e6ede1ffc193e67631f (patch)
tree8efdfe4925570ec8608d40e229ed01a5432d901e /drivers/rtc/rtc-at91sam9.c
parent45182e4e1f8ac04708ca7508c51d9103f07d81ab (diff)
parentdacb6a4035a010e41abaf81c1cfe2beadfb05ec8 (diff)
Merge tag 'rtc-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "A huge series from me this cycle. I went through many drivers to set the date and time range supported by the RTC which helps solving HW limitation when the time comes (as early as next year for some). This time, I focused on drivers using .set_mms and .set_mmss64, allowing me to remove those callbacks. About a third of the patches got reviews, I actually own the RTCs and I tested another third and the remaining one are unlikely to cause any issues. Other than that, a single new driver and the usual fixes here and there. Summary: Subsystem: - set_mmss and set_mmss64 rtc_ops removal - Fix timestamp value for RTC_TIMESTAMP_BEGIN_1900 - Use SPDX identifier for the core - validate upper bound of tm->tm_year New driver: - Aspeed BMC SoC RTC Drivers: - abx80x: use rtc_add_group - ds3232: nvram support - pcf85063: add alarm, nvram, offset correction and microcrystal rv8263 support - x1205: add of_match_table - Use set_time instead of set_mms/set_mmss64 for: ab3100, coh901331, digicolor, ds1672, ds2404, ep93xx, imxdi, jz4740, lpc32xx, mc13xxx, mxc, pcap, stmp3xxx, test, wm831x, xgene. - Set RTC range for: ab3100, at91sam9, coh901331, da9063, digicolor, dm355evm, ds1672, ds2404, ep39xx, goldfish, imxdi, jz4740, lpc32xx, mc13xxx, mv, mxc, omap, pcap, pcf85063, pcf85363, ps3, sh, stmp3xxx, sun4v, tegra, wm831x, xgene. - Switch to rtc_time64_to_tm/rtc_tm_to_time64 for the driver that properly set the RTC range. - Use dev_get_drvdata instead of multiple indirections" * tag 'rtc-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (177 commits) rtc: snvs: Use __maybe_unused instead of #if CONFIG_PM_SLEEP rtc: imxdi: remove unused variable rtc: drop set_mms and set_mmss64 rtc: pcap: convert to SPDX identifier rtc: pcap: use .set_time rtc: pcap: switch to rtc_time64_to_tm/rtc_tm_to_time64 rtc: pcap: set range rtc: digicolor: convert to SPDX identifier rtc: digicolor: use .set_time rtc: digicolor: set range rtc: digicolor: fix possible race condition rtc: jz4740: convert to SPDX identifier rtc: jz4740: rework invalid time detection rtc: jz4740: use dev_pm_set_wake_irq() to simplify code rtc: jz4740: use .set_time rtc: jz4740: remove useless check rtc: jz4740: switch to rtc_time64_to_tm/rtc_tm_to_time64 rtc: jz4740: set range rtc: 88pm860x: prevent use-after-free on device remove rtc: Use dev_get_drvdata() ...
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,