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 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include +#include #include #include #include @@ -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); } 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 = { .vcoreg = CM_AUXOSC, }; +static struct clk sp804_clk = { + .rate = 1000000, +}; + static struct clk_lookup cp_lookups[] = { { /* CLCD */ .dev_id = "mb:c0", .clk = &cp_auxclk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .clk = &sp804_clk, }, }; 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 = { .rate = 24000000, }; +static struct clk sp804_clk = { + .rate = 1000000, +}; + static struct clk dummy_apb_pclk; static struct clk_lookup lookups[] = { @@ -357,7 +361,10 @@ static struct clk_lookup lookups[] = { }, { /* SSP */ .dev_id = "dev:ssp0", .clk = &ref24_clk, - } + }, { /* SP804 timers */ + .dev_id = "sp804", + .clk = &sp804_clk, + }, }; void __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 = { .rate = 24000000, }; +static struct clk sp804_clk = { + .rate = 1000000, +}; + static struct clk dummy_apb_pclk; static struct clk_lookup lookups[] = { @@ -411,7 +415,10 @@ static struct clk_lookup lookups[] = { }, { /* CLCD */ .dev_id = "dev:20", .clk = &osc4_clk, - } + }, { /* SP804 timers */ + .dev_id = "sp804", + .clk = &sp804_clk, + }, }; /* 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 = { .rate = 24000000, }; +static struct clk ct_sp804_clk = { + .rate = 1000000, +}; + static struct clk_lookup lookups[] = { { /* CLCD */ .dev_id = "ct:clcd", .clk = &osc1_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "ct-timer1", + .clk = &ct_sp804_clk, }, }; 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 = { .rate = 24000000, }; +static struct clk v2m_sp804_clk = { + .rate = 1000000, +}; + static struct clk dummy_apb_pclk; static struct clk_lookup v2m_lookups[] = { @@ -363,6 +367,10 @@ static struct clk_lookup v2m_lookups[] = { }, { /* CLCD */ .dev_id = "mb:clcd", .clk = &osc1_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer1", + .clk = &v2m_sp804_clk, }, };