aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/clock.c12
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c8
2 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 165aa9c748f6..e028320ab423 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -86,6 +86,7 @@ static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
86 86
87 if (c->mul != 0 && c->div != 0) { 87 if (c->mul != 0 && c->div != 0) {
88 rate *= c->mul; 88 rate *= c->mul;
89 rate += c->div - 1; /* round up */
89 do_div(rate, c->div); 90 do_div(rate, c->div);
90 } 91 }
91 92
@@ -240,12 +241,23 @@ EXPORT_SYMBOL(clk_get_parent);
240 241
241int clk_set_rate_locked(struct clk *c, unsigned long rate) 242int clk_set_rate_locked(struct clk *c, unsigned long rate)
242{ 243{
244 long new_rate;
245
243 if (!c->ops || !c->ops->set_rate) 246 if (!c->ops || !c->ops->set_rate)
244 return -ENOSYS; 247 return -ENOSYS;
245 248
246 if (rate > c->max_rate) 249 if (rate > c->max_rate)
247 rate = c->max_rate; 250 rate = c->max_rate;
248 251
252 if (c->ops && c->ops->round_rate) {
253 new_rate = c->ops->round_rate(c, rate);
254
255 if (new_rate < 0)
256 return new_rate;
257
258 rate = new_rate;
259 }
260
249 return c->ops->set_rate(c, rate); 261 return c->ops->set_rate(c, rate);
250} 262}
251 263
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 2ca8b74ec07e..73e112f12695 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -898,9 +898,9 @@ static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
898 divider = clk_div71_get_divider(parent_rate, rate); 898 divider = clk_div71_get_divider(parent_rate, rate);
899 if (divider < 0) 899 if (divider < 0)
900 return divider; 900 return divider;
901 return parent_rate * 2 / (divider + 2); 901 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
902 } else if (c->flags & DIV_2) { 902 } else if (c->flags & DIV_2) {
903 return parent_rate / 2; 903 return DIV_ROUND_UP(parent_rate, 2);
904 } 904 }
905 return -EINVAL; 905 return -EINVAL;
906} 906}
@@ -1092,12 +1092,12 @@ static long tegra2_periph_clk_round_rate(struct clk *c,
1092 if (divider < 0) 1092 if (divider < 0)
1093 return divider; 1093 return divider;
1094 1094
1095 return parent_rate * 2 / (divider + 2); 1095 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1096 } else if (c->flags & DIV_U16) { 1096 } else if (c->flags & DIV_U16) {
1097 divider = clk_div16_get_divider(parent_rate, rate); 1097 divider = clk_div16_get_divider(parent_rate, rate);
1098 if (divider < 0) 1098 if (divider < 0)
1099 return divider; 1099 return divider;
1100 return parent_rate / (divider + 1); 1100 return DIV_ROUND_UP(parent_rate, divider + 1);
1101 } 1101 }
1102 return -EINVAL; 1102 return -EINVAL;
1103} 1103}