aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-05-12 08:31:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-05-23 13:04:53 -0400
commit7ff550de99141cbd3be0129d563cc4554fdde9f6 (patch)
tree21381e1dcdbd69b461cefc696a1a1fd80f38ce8e /arch
parentfb593cf38fc426331275d761fefe13096070f56a (diff)
clocksource: ARM sp804: obtain sp804 timer rate via clks
This allows platforms to specify the rate of the SP804 clocksource via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/timer-sp.c39
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c7
-rw-r--r--arch/arm/mach-realview/core.c9
-rw-r--r--arch/arm/mach-versatile/core.c9
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c8
-rw-r--r--arch/arm/mach-vexpress/v2m.c8
6 files changed, 77 insertions, 3 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
37static 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
35void __init sp804_clocksource_init(void __iomem *base, const char *name) 67void __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
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 46fb7f580fef..8fb8afb014ef 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -229,10 +229,17 @@ static struct clk cp_auxclk = {
229 .vcoreg = CM_AUXOSC, 229 .vcoreg = CM_AUXOSC,
230}; 230};
231 231
232static struct clk sp804_clk = {
233 .rate = 1000000,
234};
235
232static struct clk_lookup cp_lookups[] = { 236static struct clk_lookup cp_lookups[] = {
233 { /* CLCD */ 237 { /* CLCD */
234 .dev_id = "mb:c0", 238 .dev_id = "mb:c0",
235 .clk = &cp_auxclk, 239 .clk = &cp_auxclk,
240 }, { /* SP804 timers */
241 .dev_id = "sp804",
242 .clk = &sp804_clk,
236 }, 243 },
237}; 244};
238 245
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 6356b5e2e111..6a9cd1eb4c2e 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -315,6 +315,10 @@ static struct clk ref24_clk = {
315 .rate = 24000000, 315 .rate = 24000000,
316}; 316};
317 317
318static struct clk sp804_clk = {
319 .rate = 1000000,
320};
321
318static struct clk dummy_apb_pclk; 322static struct clk dummy_apb_pclk;
319 323
320static struct clk_lookup lookups[] = { 324static struct clk_lookup lookups[] = {
@@ -357,7 +361,10 @@ static struct clk_lookup lookups[] = {
357 }, { /* SSP */ 361 }, { /* SSP */
358 .dev_id = "dev:ssp0", 362 .dev_id = "dev:ssp0",
359 .clk = &ref24_clk, 363 .clk = &ref24_clk,
360 } 364 }, { /* SP804 timers */
365 .dev_id = "sp804",
366 .clk = &sp804_clk,
367 },
361}; 368};
362 369
363void __init realview_init_early(void) 370void __init realview_init_early(void)
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index aad6d395be44..b0b7de6875ab 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -375,6 +375,10 @@ static struct clk ref24_clk = {
375 .rate = 24000000, 375 .rate = 24000000,
376}; 376};
377 377
378static struct clk sp804_clk = {
379 .rate = 1000000,
380};
381
378static struct clk dummy_apb_pclk; 382static struct clk dummy_apb_pclk;
379 383
380static struct clk_lookup lookups[] = { 384static struct clk_lookup lookups[] = {
@@ -411,7 +415,10 @@ static struct clk_lookup lookups[] = {
411 }, { /* CLCD */ 415 }, { /* CLCD */
412 .dev_id = "dev:20", 416 .dev_id = "dev:20",
413 .clk = &osc4_clk, 417 .clk = &osc4_clk,
414 } 418 }, { /* SP804 timers */
419 .dev_id = "sp804",
420 .clk = &sp804_clk,
421 },
415}; 422};
416 423
417/* 424/*
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index c833fd9505c5..6004f06cbde5 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -141,10 +141,18 @@ static struct clk osc1_clk = {
141 .rate = 24000000, 141 .rate = 24000000,
142}; 142};
143 143
144static struct clk ct_sp804_clk = {
145 .rate = 1000000,
146};
147
144static struct clk_lookup lookups[] = { 148static struct clk_lookup lookups[] = {
145 { /* CLCD */ 149 { /* CLCD */
146 .dev_id = "ct:clcd", 150 .dev_id = "ct:clcd",
147 .clk = &osc1_clk, 151 .clk = &osc1_clk,
152 }, { /* SP804 timers */
153 .dev_id = "sp804",
154 .con_id = "ct-timer1",
155 .clk = &ct_sp804_clk,
148 }, 156 },
149}; 157};
150 158
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index ccf1f899ac21..77d5db3d7808 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -333,6 +333,10 @@ static struct clk osc2_clk = {
333 .rate = 24000000, 333 .rate = 24000000,
334}; 334};
335 335
336static struct clk v2m_sp804_clk = {
337 .rate = 1000000,
338};
339
336static struct clk dummy_apb_pclk; 340static struct clk dummy_apb_pclk;
337 341
338static struct clk_lookup v2m_lookups[] = { 342static struct clk_lookup v2m_lookups[] = {
@@ -363,6 +367,10 @@ static struct clk_lookup v2m_lookups[] = {
363 }, { /* CLCD */ 367 }, { /* CLCD */
364 .dev_id = "mb:clcd", 368 .dev_id = "mb:clcd",
365 .clk = &osc1_clk, 369 .clk = &osc1_clk,
370 }, { /* SP804 timers */
371 .dev_id = "sp804",
372 .con_id = "v2m-timer1",
373 .clk = &v2m_sp804_clk,
366 }, 374 },
367}; 375};
368 376