Skip to content

Commit

Permalink
rtc: at91sam9: use clk API instead of relying on AT91_SLOW_CLOCK
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Boris BREZILLON authored and Nicolas Ferre committed Nov 13, 2014
1 parent a982502 commit a975f47
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions drivers/rtc/rtc-at91sam9.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/clk.h>

/*
* This driver uses two configurable hardware resources that live in the
Expand Down Expand Up @@ -61,8 +62,6 @@
#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */

#define AT91_SLOW_CLOCK 32768

/*
* We store ALARM_DISABLED in ALMV to record that no alarm is set.
* It's also the reset value for that field.
Expand All @@ -77,6 +76,7 @@ struct sam9_rtc {
struct regmap *gpbr;
unsigned int gpbr_offset;
int irq;
struct clk *sclk;
};

#define rtt_readl(rtc, field) \
Expand Down Expand Up @@ -328,6 +328,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
struct sam9_rtc *rtc;
int ret, irq;
u32 mr;
unsigned int sclk_rate;

irq = platform_get_irq(pdev, 0);
if (irq < 0) {
Expand Down Expand Up @@ -385,11 +386,27 @@ static int at91_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
}

rtc->sclk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(rtc->sclk))
return PTR_ERR(rtc->sclk);

sclk_rate = clk_get_rate(rtc->sclk);
if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) {
dev_err(&pdev->dev, "Invalid slow clock rate\n");
return -EINVAL;
}

ret = clk_prepare_enable(rtc->sclk);
if (ret) {
dev_err(&pdev->dev, "Could not enable slow clock\n");
return ret;
}

mr = rtt_readl(rtc, MR);

/* unless RTT is counting at 1 Hz, re-initialize it */
if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) {
mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES);
if ((mr & AT91_RTT_RTPRES) != sclk_rate) {
mr = AT91_RTT_RTTRST | (sclk_rate & AT91_RTT_RTPRES);
gpbr_writel(rtc, 0);
}

Expand Down Expand Up @@ -434,6 +451,9 @@ static int at91_rtc_remove(struct platform_device *pdev)
/* disable all interrupts */
rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));

if (!IS_ERR(rtc->sclk))
clk_disable_unprepare(rtc->sclk);

return 0;
}

Expand Down

0 comments on commit a975f47

Please sign in to comment.