diff options
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 8 |
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 | ||
241 | int clk_set_rate_locked(struct clk *c, unsigned long rate) | 242 | int 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 | } |