aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-11-20 07:42:21 -0500
committerArnd Bergmann <arnd@arndb.de>2014-11-20 07:42:21 -0500
commitc3e6dc65f2ce83dacc0a18104bf44931e7eb8a5d (patch)
treec2e1420d066463a15d6b28b2dc1588353d88b63c /drivers/rtc
parent27bc375a9c50f70a9c600a6771cc50ffd5cf8c98 (diff)
parent2c91e61dc97cce57ffd9dd654a6ee284e1f45a1f (diff)
Merge tag 'at91-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 into next/drivers
Pull "First batch of drivers for 3.19" from Nicolas Ferre: It is only about a not so recent driver for old platforms: RTT as RTC driver: - RTT as RTC driver enhancements and machine specific include files removal - RTT as RTC driver conversion to device tree * tag 'at91-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91: rtc: at91sam9: add DT bindings documentation rtc: at91sam9: use clk API instead of relying on AT91_SLOW_CLOCK ARM: at91: add clk_lookup entry for RTT devices rtc: at91sam9: rework the Kconfig description rtc: at91sam9: make use of syscon/regmap to access GPBR registers rtc: at91sam9: add DT support rtc: at91sam9: replace devm_ioremap by devm_ioremap_resource rtc: at91sam9: use standard readl/writel functions instead of raw versions rtc: at91sam9: remove references to mach specific headers Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig24
-rw-r--r--drivers/rtc/rtc-at91sam9.c138
2 files changed, 125 insertions, 37 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6dd12ddbabc6..77eb13cabe6d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1109,16 +1109,18 @@ config RTC_DRV_AT91RM9200
1109 this is powered by the backup power supply. 1109 this is powered by the backup power supply.
1110 1110
1111config RTC_DRV_AT91SAM9 1111config RTC_DRV_AT91SAM9
1112 tristate "AT91SAM9x/AT91CAP9 RTT as RTC" 1112 tristate "AT91SAM9 RTT as RTC"
1113 depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) 1113 depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
1114 select MFD_SYSCON
1114 help 1115 help
1115 RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT 1116 Some AT91SAM9 SoCs provide an RTT (Real Time Timer) block which
1116 (Real Time Timer). These timers are powered by the backup power 1117 can be used as an RTC thanks to the backup power supply (e.g. a
1117 supply (such as a small coin cell battery), but do not need to 1118 small coin cell battery) which keeps this block and the GPBR
1118 be used as RTCs. 1119 (General Purpose Backup Registers) block powered when the device
1119 1120 is shutdown.
1120 (On AT91SAM9rl and AT91SAM9G45 chips you probably want to use the 1121 Some AT91SAM9 SoCs provide a real RTC block, on those ones you'd
1121 dedicated RTC module and leave the RTT available for other uses.) 1122 probably want to use the real RTC block instead of the "RTT as an
1123 RTC" driver.
1122 1124
1123config RTC_DRV_AT91SAM9_RTT 1125config RTC_DRV_AT91SAM9_RTT
1124 int 1126 int
@@ -1127,6 +1129,9 @@ config RTC_DRV_AT91SAM9_RTT
1127 prompt "RTT module Number" if ARCH_AT91SAM9263 1129 prompt "RTT module Number" if ARCH_AT91SAM9263
1128 depends on RTC_DRV_AT91SAM9 1130 depends on RTC_DRV_AT91SAM9
1129 help 1131 help
1132 This option is only relevant for legacy board support and
1133 won't be used when booting a DT board.
1134
1130 More than one RTT module is available. You can choose which 1135 More than one RTT module is available. You can choose which
1131 one will be used as an RTC. The default of zero is normally 1136 one will be used as an RTC. The default of zero is normally
1132 OK to use, though some systems use that for non-RTC purposes. 1137 OK to use, though some systems use that for non-RTC purposes.
@@ -1139,6 +1144,9 @@ config RTC_DRV_AT91SAM9_GPBR
1139 prompt "Backup Register Number" 1144 prompt "Backup Register Number"
1140 depends on RTC_DRV_AT91SAM9 1145 depends on RTC_DRV_AT91SAM9
1141 help 1146 help
1147 This option is only relevant for legacy board support and
1148 won't be used when booting a DT board.
1149
1142 The RTC driver needs to use one of the General Purpose Backup 1150 The RTC driver needs to use one of the General Purpose Backup
1143 Registers (GPBRs) as well as the RTT. You can choose which one 1151 Registers (GPBRs) as well as the RTT. You can choose which one
1144 will be used. The default of zero is normally OK to use, but 1152 will be used. The default of zero is normally OK to use, but
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 596374304532..abac38abd38e 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -21,10 +21,9 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/platform_data/atmel.h> 22#include <linux/platform_data/atmel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/mfd/syscon.h>
25#include <mach/at91_rtt.h> 25#include <linux/regmap.h>
26#include <mach/cpu.h> 26#include <linux/clk.h>
27#include <mach/hardware.h>
28 27
29/* 28/*
30 * This driver uses two configurable hardware resources that live in the 29 * This driver uses two configurable hardware resources that live in the
@@ -47,6 +46,22 @@
47 * registers available, likewise usable for more than "RTC" support. 46 * registers available, likewise usable for more than "RTC" support.
48 */ 47 */
49 48
49#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
50#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */
51#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
52#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
53#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */
54
55#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
56#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
57
58#define AT91_RTT_VR 0x08 /* Real-time Value Register */
59#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
60
61#define AT91_RTT_SR 0x0c /* Real-time Status Register */
62#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
63#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
64
50/* 65/*
51 * We store ALARM_DISABLED in ALMV to record that no alarm is set. 66 * We store ALARM_DISABLED in ALMV to record that no alarm is set.
52 * It's also the reset value for that field. 67 * It's also the reset value for that field.
@@ -58,19 +73,30 @@ struct sam9_rtc {
58 void __iomem *rtt; 73 void __iomem *rtt;
59 struct rtc_device *rtcdev; 74 struct rtc_device *rtcdev;
60 u32 imr; 75 u32 imr;
61 void __iomem *gpbr; 76 struct regmap *gpbr;
77 unsigned int gpbr_offset;
62 int irq; 78 int irq;
79 struct clk *sclk;
63}; 80};
64 81
65#define rtt_readl(rtc, field) \ 82#define rtt_readl(rtc, field) \
66 __raw_readl((rtc)->rtt + AT91_RTT_ ## field) 83 readl((rtc)->rtt + AT91_RTT_ ## field)
67#define rtt_writel(rtc, field, val) \ 84#define rtt_writel(rtc, field, val) \
68 __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) 85 writel((val), (rtc)->rtt + AT91_RTT_ ## field)
86
87static inline unsigned int gpbr_readl(struct sam9_rtc *rtc)
88{
89 unsigned int val;
90
91 regmap_read(rtc->gpbr, rtc->gpbr_offset, &val);
69 92
70#define gpbr_readl(rtc) \ 93 return val;
71 __raw_readl((rtc)->gpbr) 94}
72#define gpbr_writel(rtc, val) \ 95
73 __raw_writel((val), (rtc)->gpbr) 96static inline void gpbr_writel(struct sam9_rtc *rtc, unsigned int val)
97{
98 regmap_write(rtc->gpbr, rtc->gpbr_offset, val);
99}
74 100
75/* 101/*
76 * Read current time and date in RTC 102 * Read current time and date in RTC
@@ -287,22 +313,22 @@ static const struct rtc_class_ops at91_rtc_ops = {
287 .alarm_irq_enable = at91_rtc_alarm_irq_enable, 313 .alarm_irq_enable = at91_rtc_alarm_irq_enable,
288}; 314};
289 315
316static struct regmap_config gpbr_regmap_config = {
317 .reg_bits = 32,
318 .val_bits = 32,
319 .reg_stride = 4,
320};
321
290/* 322/*
291 * Initialize and install RTC driver 323 * Initialize and install RTC driver
292 */ 324 */
293static int at91_rtc_probe(struct platform_device *pdev) 325static int at91_rtc_probe(struct platform_device *pdev)
294{ 326{
295 struct resource *r, *r_gpbr; 327 struct resource *r;
296 struct sam9_rtc *rtc; 328 struct sam9_rtc *rtc;
297 int ret, irq; 329 int ret, irq;
298 u32 mr; 330 u32 mr;
299 331 unsigned int sclk_rate;
300 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
301 r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
302 if (!r || !r_gpbr) {
303 dev_err(&pdev->dev, "need 2 ressources\n");
304 return -ENODEV;
305 }
306 332
307 irq = platform_get_irq(pdev, 0); 333 irq = platform_get_irq(pdev, 0);
308 if (irq < 0) { 334 if (irq < 0) {
@@ -321,24 +347,66 @@ static int at91_rtc_probe(struct platform_device *pdev)
321 device_init_wakeup(&pdev->dev, 1); 347 device_init_wakeup(&pdev->dev, 1);
322 348
323 platform_set_drvdata(pdev, rtc); 349 platform_set_drvdata(pdev, rtc);
324 rtc->rtt = devm_ioremap(&pdev->dev, r->start, resource_size(r)); 350
325 if (!rtc->rtt) { 351 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
326 dev_err(&pdev->dev, "failed to map registers, aborting.\n"); 352 rtc->rtt = devm_ioremap_resource(&pdev->dev, r);
327 return -ENOMEM; 353 if (IS_ERR(rtc->rtt))
354 return PTR_ERR(rtc->rtt);
355
356 if (!pdev->dev.of_node) {
357 /*
358 * TODO: Remove this code chunk when removing non DT board
359 * support. Remember to remove the gpbr_regmap_config
360 * variable too.
361 */
362 void __iomem *gpbr;
363
364 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
365 gpbr = devm_ioremap_resource(&pdev->dev, r);
366 if (IS_ERR(gpbr))
367 return PTR_ERR(gpbr);
368
369 rtc->gpbr = regmap_init_mmio(NULL, gpbr,
370 &gpbr_regmap_config);
371 } else {
372 struct of_phandle_args args;
373
374 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
375 "atmel,rtt-rtc-time-reg", 1, 0,
376 &args);
377 if (ret)
378 return ret;
379
380 rtc->gpbr = syscon_node_to_regmap(args.np);
381 rtc->gpbr_offset = args.args[0];
328 } 382 }
329 383
330 rtc->gpbr = devm_ioremap(&pdev->dev, r_gpbr->start, 384 if (IS_ERR(rtc->gpbr)) {
331 resource_size(r_gpbr)); 385 dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n");
332 if (!rtc->gpbr) {
333 dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n");
334 return -ENOMEM; 386 return -ENOMEM;
335 } 387 }
336 388
389 rtc->sclk = devm_clk_get(&pdev->dev, NULL);
390 if (IS_ERR(rtc->sclk))
391 return PTR_ERR(rtc->sclk);
392
393 sclk_rate = clk_get_rate(rtc->sclk);
394 if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) {
395 dev_err(&pdev->dev, "Invalid slow clock rate\n");
396 return -EINVAL;
397 }
398
399 ret = clk_prepare_enable(rtc->sclk);
400 if (ret) {
401 dev_err(&pdev->dev, "Could not enable slow clock\n");
402 return ret;
403 }
404
337 mr = rtt_readl(rtc, MR); 405 mr = rtt_readl(rtc, MR);
338 406
339 /* unless RTT is counting at 1 Hz, re-initialize it */ 407 /* unless RTT is counting at 1 Hz, re-initialize it */
340 if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) { 408 if ((mr & AT91_RTT_RTPRES) != sclk_rate) {
341 mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES); 409 mr = AT91_RTT_RTTRST | (sclk_rate & AT91_RTT_RTPRES);
342 gpbr_writel(rtc, 0); 410 gpbr_writel(rtc, 0);
343 } 411 }
344 412
@@ -383,6 +451,9 @@ static int at91_rtc_remove(struct platform_device *pdev)
383 /* disable all interrupts */ 451 /* disable all interrupts */
384 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); 452 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
385 453
454 if (!IS_ERR(rtc->sclk))
455 clk_disable_unprepare(rtc->sclk);
456
386 return 0; 457 return 0;
387} 458}
388 459
@@ -440,6 +511,14 @@ static int at91_rtc_resume(struct device *dev)
440 511
441static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); 512static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
442 513
514#ifdef CONFIG_OF
515static const struct of_device_id at91_rtc_dt_ids[] = {
516 { .compatible = "atmel,at91sam9260-rtt" },
517 { /* sentinel */ }
518};
519MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
520#endif
521
443static struct platform_driver at91_rtc_driver = { 522static struct platform_driver at91_rtc_driver = {
444 .probe = at91_rtc_probe, 523 .probe = at91_rtc_probe,
445 .remove = at91_rtc_remove, 524 .remove = at91_rtc_remove,
@@ -448,6 +527,7 @@ static struct platform_driver at91_rtc_driver = {
448 .name = "rtc-at91sam9", 527 .name = "rtc-at91sam9",
449 .owner = THIS_MODULE, 528 .owner = THIS_MODULE,
450 .pm = &at91_rtc_pm_ops, 529 .pm = &at91_rtc_pm_ops,
530 .of_match_table = of_match_ptr(at91_rtc_dt_ids),
451 }, 531 },
452}; 532};
453 533