diff options
Diffstat (limited to 'arch/arm/common/timer-sp.c')
-rw-r--r-- | arch/arm/common/timer-sp.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index f6b9011744aa..166f892a24d5 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c | |||
@@ -18,8 +18,10 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #include <linux/clk.h> | ||
21 | #include <linux/clocksource.h> | 22 | #include <linux/clocksource.h> |
22 | #include <linux/clockchips.h> | 23 | #include <linux/clockchips.h> |
24 | #include <linux/err.h> | ||
23 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
25 | #include <linux/io.h> | 27 | #include <linux/io.h> |
@@ -32,8 +34,43 @@ | |||
32 | #define TIMER_FREQ_KHZ (1000) | 34 | #define TIMER_FREQ_KHZ (1000) |
33 | #define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) | 35 | #define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) |
34 | 36 | ||
37 | static long __init sp804_get_clock_rate(const char *name) | ||
38 | { | ||
39 | struct clk *clk; | ||
40 | long rate; | ||
41 | int err; | ||
42 | |||
43 | clk = clk_get_sys("sp804", name); | ||
44 | if (IS_ERR(clk)) { | ||
45 | pr_err("sp804: %s clock not found: %d\n", name, | ||
46 | (int)PTR_ERR(clk)); | ||
47 | return PTR_ERR(clk); | ||
48 | } | ||
49 | |||
50 | err = clk_enable(clk); | ||
51 | if (err) { | ||
52 | pr_err("sp804: %s clock failed to enable: %d\n", name, err); | ||
53 | clk_put(clk); | ||
54 | return err; | ||
55 | } | ||
56 | |||
57 | rate = clk_get_rate(clk); | ||
58 | if (rate < 0) { | ||
59 | pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate); | ||
60 | clk_disable(clk); | ||
61 | clk_put(clk); | ||
62 | } | ||
63 | |||
64 | return rate; | ||
65 | } | ||
66 | |||
35 | void __init sp804_clocksource_init(void __iomem *base, const char *name) | 67 | void __init sp804_clocksource_init(void __iomem *base, const char *name) |
36 | { | 68 | { |
69 | long rate = sp804_get_clock_rate(name); | ||
70 | |||
71 | if (rate < 0) | ||
72 | return; | ||
73 | |||
37 | /* setup timer 0 as free-running clocksource */ | 74 | /* setup timer 0 as free-running clocksource */ |
38 | writel(0, base + TIMER_CTRL); | 75 | writel(0, base + TIMER_CTRL); |
39 | writel(0xffffffff, base + TIMER_LOAD); | 76 | writel(0xffffffff, base + TIMER_LOAD); |
@@ -42,7 +79,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name) | |||
42 | base + TIMER_CTRL); | 79 | base + TIMER_CTRL); |
43 | 80 | ||
44 | clocksource_mmio_init(base + TIMER_VALUE, name, | 81 | clocksource_mmio_init(base + TIMER_VALUE, name, |
45 | TIMER_FREQ_KHZ * 1000, 200, 32, clocksource_mmio_readl_down); | 82 | rate, 200, 32, clocksource_mmio_readl_down); |
46 | } | 83 | } |
47 | 84 | ||
48 | 85 | ||