summaryrefslogtreecommitdiffstats
path: root/arch/arm/common/timer-sp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common/timer-sp.c')
-rw-r--r--arch/arm/common/timer-sp.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index f6b9011744a..166f892a24d 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -18,8 +18,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/clk.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
@@ -32,8 +34,43 @@
#define TIMER_FREQ_KHZ (1000)
#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ)
+static long __init sp804_get_clock_rate(const char *name)
+{
+ struct clk *clk;
+ long rate;
+ int err;
+
+ clk = clk_get_sys("sp804", name);
+ if (IS_ERR(clk)) {
+ pr_err("sp804: %s clock not found: %d\n", name,
+ (int)PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+
+ err = clk_enable(clk);
+ if (err) {
+ pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+ clk_put(clk);
+ return err;
+ }
+
+ rate = clk_get_rate(clk);
+ if (rate < 0) {
+ pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+ clk_disable(clk);
+ clk_put(clk);
+ }
+
+ return rate;
+}
+
void __init sp804_clocksource_init(void __iomem *base, const char *name)
{
+ long rate = sp804_get_clock_rate(name);
+
+ if (rate < 0)
+ return;
+
/* setup timer 0 as free-running clocksource */
writel(0, base + TIMER_CTRL);
writel(0xffffffff, base + TIMER_LOAD);
@@ -42,7 +79,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
base + TIMER_CTRL);
clocksource_mmio_init(base + TIMER_VALUE, name,
- TIMER_FREQ_KHZ * 1000, 200, 32, clocksource_mmio_readl_down);
+ rate, 200, 32, clocksource_mmio_readl_down);
}