aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-at91sam9.c
diff options
context:
space:
mode:
authorBoris BREZILLON <boris.brezillon@free-electrons.com>2014-09-23 10:41:07 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2014-11-13 10:08:01 -0500
commita975f47f6e9a4e9762c81973cf2305003aa5b7dc (patch)
tree3087c457ca561f407dd86baa915f19b56643d134 /drivers/rtc/rtc-at91sam9.c
parenta98250217997f3b8d47d21ffaedd39b32d1798eb (diff)
rtc: at91sam9: use clk API instead of relying on AT91_SLOW_CLOCK
The RTT block is using the slow clock which is accessible through the clk API. Use the clk API to retrieve, enable and get the slow clk rate instead of the AT91_SLOW_CLOCK macro (which hardcodes the slow clk rate). Doing this allows us to reference the clk thus preventing the CCF from disabling it during the "disable unused" phase. Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com> Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Johan Hovold <johan@kernel.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'drivers/rtc/rtc-at91sam9.c')
-rw-r--r--drivers/rtc/rtc-at91sam9.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index be9c28b9d057..abac38abd38e 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -23,6 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/mfd/syscon.h> 24#include <linux/mfd/syscon.h>
25#include <linux/regmap.h> 25#include <linux/regmap.h>
26#include <linux/clk.h>
26 27
27/* 28/*
28 * This driver uses two configurable hardware resources that live in the 29 * This driver uses two configurable hardware resources that live in the
@@ -61,8 +62,6 @@
61#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ 62#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
62#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ 63#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
63 64
64#define AT91_SLOW_CLOCK 32768
65
66/* 65/*
67 * 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.
68 * It's also the reset value for that field. 67 * It's also the reset value for that field.
@@ -77,6 +76,7 @@ struct sam9_rtc {
77 struct regmap *gpbr; 76 struct regmap *gpbr;
78 unsigned int gpbr_offset; 77 unsigned int gpbr_offset;
79 int irq; 78 int irq;
79 struct clk *sclk;
80}; 80};
81 81
82#define rtt_readl(rtc, field) \ 82#define rtt_readl(rtc, field) \
@@ -328,6 +328,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
328 struct sam9_rtc *rtc; 328 struct sam9_rtc *rtc;
329 int ret, irq; 329 int ret, irq;
330 u32 mr; 330 u32 mr;
331 unsigned int sclk_rate;
331 332
332 irq = platform_get_irq(pdev, 0); 333 irq = platform_get_irq(pdev, 0);
333 if (irq < 0) { 334 if (irq < 0) {
@@ -385,11 +386,27 @@ static int at91_rtc_probe(struct platform_device *pdev)
385 return -ENOMEM; 386 return -ENOMEM;
386 } 387 }
387 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
388 mr = rtt_readl(rtc, MR); 405 mr = rtt_readl(rtc, MR);
389 406
390 /* unless RTT is counting at 1 Hz, re-initialize it */ 407 /* unless RTT is counting at 1 Hz, re-initialize it */
391 if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) { 408 if ((mr & AT91_RTT_RTPRES) != sclk_rate) {
392 mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES); 409 mr = AT91_RTT_RTTRST | (sclk_rate & AT91_RTT_RTPRES);
393 gpbr_writel(rtc, 0); 410 gpbr_writel(rtc, 0);
394 } 411 }
395 412
@@ -434,6 +451,9 @@ static int at91_rtc_remove(struct platform_device *pdev)
434 /* disable all interrupts */ 451 /* disable all interrupts */
435 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); 452 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
436 453
454 if (!IS_ERR(rtc->sclk))
455 clk_disable_unprepare(rtc->sclk);
456
437 return 0; 457 return 0;
438} 458}
439 459