*/
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/smp.h>
 #include <linux/jiffies.h>
 #include <linux/clockchips.h>
 /* set up by the platform code */
 void __iomem *twd_base;
 
+static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
 
 static struct clock_event_device __percpu **twd_evt;
        return IRQ_NONE;
 }
 
+static struct clk *twd_get_clock(void)
+{
+       struct clk *clk;
+       int err;
+
+       clk = clk_get_sys("smp_twd", NULL);
+       if (IS_ERR(clk)) {
+               pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
+               return clk;
+       }
+
+       err = clk_prepare(clk);
+       if (err) {
+               pr_err("smp_twd: clock failed to prepare: %d\n", err);
+               clk_put(clk);
+               return ERR_PTR(err);
+       }
+
+       err = clk_enable(clk);
+       if (err) {
+               pr_err("smp_twd: clock failed to enable: %d\n", err);
+               clk_unprepare(clk);
+               clk_put(clk);
+               return ERR_PTR(err);
+       }
+
+       return clk;
+}
+
 /*
  * Setup the local clock events for a CPU.
  */
                }
        }
 
-       twd_calibrate_rate();
+       if (!twd_clk)
+               twd_clk = twd_get_clock();
+
+       if (!IS_ERR_OR_NULL(twd_clk))
+               twd_timer_rate = clk_get_rate(twd_clk);
+       else
+               twd_calibrate_rate();
 
        clk->name = "local_timer";
        clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |