@@ -161,11 +161,30 @@ static __init int timer_of_base_init(struct device_node *np,
return 0;
}
+static __init int timer_of_clk_frequency_init(struct device_node *np,
+ struct of_timer_clk *of_clk)
+{
+ int ret;
+ u32 rate;
+
+ ret = of_property_read_u32(np, "clock-frequency", &rate);
+ if (!ret) {
+ of_clk->rate = rate;
+ of_clk->period = DIV_ROUND_UP(rate, HZ);
+ }
+
+ return ret;
+}
+
int __init timer_of_init(struct device_node *np, struct timer_of *to)
{
+ unsigned long clock_flags = TIMER_OF_CLOCK | TIMER_OF_CLOCK_FREQUENCY;
int ret = -EINVAL;
int flags = 0;
+ if (to->flags & clock_flags == clock_flags)
+ return ret;
+
if (to->flags & TIMER_OF_BASE) {
ret = timer_of_base_init(np, &to->of_base);
if (ret)
@@ -180,6 +199,13 @@ int __init timer_of_init(struct device_node *np, struct timer_of *to)
flags |= TIMER_OF_CLOCK;
}
+ if (to->flags & TIMER_OF_CLOCK_FREQUENCY) {
+ ret = timer_of_clk_frequency_init(np, &to->of_clk);
+ if (ret)
+ goto out_fail;
+ flags |= TIMER_OF_CLOCK_FREQUENCY;
+ }
+
if (to->flags & TIMER_OF_IRQ) {
ret = timer_of_irq_init(np, &to->of_irq);
if (ret)
@@ -201,6 +227,9 @@ int __init timer_of_init(struct device_node *np, struct timer_of *to)
if (flags & TIMER_OF_CLOCK)
timer_of_clk_exit(&to->of_clk);
+ if (flags & TIMER_OF_CLOCK_FREQUENCY)
+ to->of_clk.rate = 0;
+
if (flags & TIMER_OF_BASE)
timer_of_base_exit(&to->of_base);
return ret;
@@ -4,9 +4,10 @@
#include <linux/clockchips.h>
-#define TIMER_OF_BASE 0x1
-#define TIMER_OF_CLOCK 0x2
-#define TIMER_OF_IRQ 0x4
+#define TIMER_OF_BASE 0x1
+#define TIMER_OF_CLOCK 0x2
+#define TIMER_OF_IRQ 0x4
+#define TIMER_OF_CLOCK_FREQUENCY 0x8
struct of_timer_irq {
int irq;