Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+77 -3
+38 -1
arch/arm/common/timer-sp.c
··· 18 18 * along with this program; if not, write to the Free Software 19 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 20 */ 21 + #include <linux/clk.h> 21 22 #include <linux/clocksource.h> 22 23 #include <linux/clockchips.h> 24 + #include <linux/err.h> 23 25 #include <linux/interrupt.h> 24 26 #include <linux/irq.h> 25 27 #include <linux/io.h> ··· 34 32 #define TIMER_FREQ_KHZ (1000) 35 33 #define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) 36 34 35 + static long __init sp804_get_clock_rate(const char *name) 36 + { 37 + struct clk *clk; 38 + long rate; 39 + int err; 40 + 41 + clk = clk_get_sys("sp804", name); 42 + if (IS_ERR(clk)) { 43 + pr_err("sp804: %s clock not found: %d\n", name, 44 + (int)PTR_ERR(clk)); 45 + return PTR_ERR(clk); 46 + } 47 + 48 + err = clk_enable(clk); 49 + if (err) { 50 + pr_err("sp804: %s clock failed to enable: %d\n", name, err); 51 + clk_put(clk); 52 + return err; 53 + } 54 + 55 + rate = clk_get_rate(clk); 56 + if (rate < 0) { 57 + pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate); 58 + clk_disable(clk); 59 + clk_put(clk); 60 + } 61 + 62 + return rate; 63 + } 64 + 37 65 void __init sp804_clocksource_init(void __iomem *base, const char *name) 38 66 { 67 + long rate = sp804_get_clock_rate(name); 68 + 69 + if (rate < 0) 70 + return; 71 + 39 72 /* setup timer 0 as free-running clocksource */ 40 73 writel(0, base + TIMER_CTRL); 41 74 writel(0xffffffff, base + TIMER_LOAD); ··· 79 42 base + TIMER_CTRL); 80 43 81 44 clocksource_mmio_init(base + TIMER_VALUE, name, 82 - TIMER_FREQ_KHZ * 1000, 200, 32, clocksource_mmio_readl_down); 45 + rate, 200, 32, clocksource_mmio_readl_down); 83 46 } 84 47 85 48
+7
arch/arm/mach-integrator/integrator_cp.c
··· 229 229 .vcoreg = CM_AUXOSC, 230 230 }; 231 231 232 + static struct clk sp804_clk = { 233 + .rate = 1000000, 234 + }; 235 + 232 236 static struct clk_lookup cp_lookups[] = { 233 237 { /* CLCD */ 234 238 .dev_id = "mb:c0", 235 239 .clk = &cp_auxclk, 240 + }, { /* SP804 timers */ 241 + .dev_id = "sp804", 242 + .clk = &sp804_clk, 236 243 }, 237 244 }; 238 245
+8 -1
arch/arm/mach-realview/core.c
··· 315 315 .rate = 24000000, 316 316 }; 317 317 318 + static struct clk sp804_clk = { 319 + .rate = 1000000, 320 + }; 321 + 318 322 static struct clk dummy_apb_pclk; 319 323 320 324 static struct clk_lookup lookups[] = { ··· 361 357 }, { /* SSP */ 362 358 .dev_id = "dev:ssp0", 363 359 .clk = &ref24_clk, 364 - } 360 + }, { /* SP804 timers */ 361 + .dev_id = "sp804", 362 + .clk = &sp804_clk, 363 + }, 365 364 }; 366 365 367 366 void __init realview_init_early(void)
+8 -1
arch/arm/mach-versatile/core.c
··· 375 375 .rate = 24000000, 376 376 }; 377 377 378 + static struct clk sp804_clk = { 379 + .rate = 1000000, 380 + }; 381 + 378 382 static struct clk dummy_apb_pclk; 379 383 380 384 static struct clk_lookup lookups[] = { ··· 415 411 }, { /* CLCD */ 416 412 .dev_id = "dev:20", 417 413 .clk = &osc4_clk, 418 - } 414 + }, { /* SP804 timers */ 415 + .dev_id = "sp804", 416 + .clk = &sp804_clk, 417 + }, 419 418 }; 420 419 421 420 /*
+8
arch/arm/mach-vexpress/ct-ca9x4.c
··· 141 141 .rate = 24000000, 142 142 }; 143 143 144 + static struct clk ct_sp804_clk = { 145 + .rate = 1000000, 146 + }; 147 + 144 148 static struct clk_lookup lookups[] = { 145 149 { /* CLCD */ 146 150 .dev_id = "ct:clcd", 147 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
+8
arch/arm/mach-vexpress/v2m.c
··· 333 333 .rate = 24000000, 334 334 }; 335 335 336 + static struct clk v2m_sp804_clk = { 337 + .rate = 1000000, 338 + }; 339 + 336 340 static struct clk dummy_apb_pclk; 337 341 338 342 static struct clk_lookup v2m_lookups[] = { ··· 367 363 }, { /* CLCD */ 368 364 .dev_id = "mb:clcd", 369 365 .clk = &osc1_clk, 366 + }, { /* SP804 timers */ 367 + .dev_id = "sp804", 368 + .con_id = "v2m-timer1", 369 + .clk = &v2m_sp804_clk, 370 370 }, 371 371 }; 372 372