[ARM/tegra] Add Tegra3 support
[linux-2.6.git] / arch / arm / mach-tegra / clock.c
index 889c032..0096f6f 100644 (file)
@@ -103,6 +103,9 @@ static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
 
        rate = clk_get_rate(p);
 
+       if (c->ops && c->ops->recalculate_rate)
+               c->ops->recalculate_rate(c);
+
        if (c->mul != 0 && c->div != 0) {
                rate *= c->mul;
                rate += c->div - 1; /* round up */
@@ -311,13 +314,16 @@ EXPORT_SYMBOL(clk_get_parent);
 int clk_set_rate_locked(struct clk *c, unsigned long rate)
 {
        int ret = 0;
-       unsigned long old_rate;
+       unsigned long old_rate, max_rate;
        long new_rate;
 
        old_rate = clk_get_rate_locked(c);
 
-       if (rate > c->max_rate)
-               rate = c->max_rate;
+       max_rate = c->max_rate;
+       if (c->ops && c->ops->get_max_rate)
+               max_rate = c->ops->get_max_rate(c);
+       if (rate > max_rate)
+               rate = max_rate;
 
        if (c->ops && c->ops->round_rate) {
                new_rate = c->ops->round_rate(c, rate);
@@ -374,6 +380,8 @@ unsigned long clk_get_rate_all_locked(struct clk *c)
 
        while (p) {
                c = p;
+               if (c->ops && c->ops->recalculate_rate)
+                       c->ops->recalculate_rate(c);
                if (c->mul != 0 && c->div != 0) {
                        mul *= c->mul;
                        div *= c->div;
@@ -390,7 +398,7 @@ unsigned long clk_get_rate_all_locked(struct clk *c)
 
 long clk_round_rate(struct clk *c, unsigned long rate)
 {
-       unsigned long flags;
+       unsigned long flags, max_rate;
        long ret;
 
        clk_lock_save(c, &flags);
@@ -400,8 +408,11 @@ long clk_round_rate(struct clk *c, unsigned long rate)
                goto out;
        }
 
-       if (rate > c->max_rate)
-               rate = c->max_rate;
+       max_rate = c->max_rate;
+       if (c->ops && c->ops->get_max_rate)
+               max_rate = c->ops->get_max_rate(c);
+       if (rate > max_rate)
+               rate = max_rate;
 
        ret = c->ops->round_rate(c, rate);
 
@@ -474,20 +485,22 @@ EXPORT_SYMBOL(tegra_clk_init_from_table);
 
 void tegra_periph_reset_deassert(struct clk *c)
 {
-       tegra2_periph_reset_deassert(c);
+       BUG_ON(!c->ops->reset);
+       c->ops->reset(c, false);
 }
 EXPORT_SYMBOL(tegra_periph_reset_deassert);
 
 void tegra_periph_reset_assert(struct clk *c)
 {
-       tegra2_periph_reset_assert(c);
+       BUG_ON(!c->ops->reset);
+       c->ops->reset(c, true);
 }
 EXPORT_SYMBOL(tegra_periph_reset_assert);
 
 void __init tegra_init_clock(void)
 {
-       tegra2_init_clocks();
-       tegra2_init_dvfs();
+       tegra_soc_init_clocks();
+       tegra_soc_init_dvfs();
 }
 
 /*
@@ -676,6 +689,11 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
        struct clk *child;
        const char *state = "uninit";
        char div[8] = {0};
+       unsigned long rate = clk_get_rate_all_locked(c);
+       unsigned long max_rate = c->max_rate;
+
+       if (c->ops && c->ops->get_max_rate)
+               max_rate = c->ops->get_max_rate(c);
 
        if (c->state == ON)
                state = "on";
@@ -701,10 +719,10 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
 
        seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
                level * 3 + 1, "",
-               c->rate > c->max_rate ? '!' : ' ',
+               rate > max_rate ? '!' : ' ',
                !c->set ? '*' : ' ',
                30 - level * 3, c->name,
-               state, c->refcnt, div, clk_get_rate_all_locked(c));
+               state, c->refcnt, div, rate);
 
        if (c->dvfs)
                dvfs_show_one(s, c->dvfs, level + 1);
@@ -873,6 +891,10 @@ static int clk_debugfs_register_one(struct clk *c)
        if (!d)
                goto err_out;
 
+       d = debugfs_create_u32("max", S_IRUGO, c->dent, (u32 *)&c->max_rate);
+       if (!d)
+               goto err_out;
+
        d = debugfs_create_file(
                "parent", parent_rate_mode, c->dent, c, &parent_fops);
        if (!d)