aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/clk.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8e728f395b54..efbc802da3b3 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2000,6 +2000,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate_exclusive);
2000int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) 2000int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
2001{ 2001{
2002 int ret = 0; 2002 int ret = 0;
2003 unsigned long old_min, old_max, rate;
2003 2004
2004 if (!clk) 2005 if (!clk)
2005 return 0; 2006 return 0;
@@ -2016,10 +2017,38 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
2016 if (clk->exclusive_count) 2017 if (clk->exclusive_count)
2017 clk_core_rate_unprotect(clk->core); 2018 clk_core_rate_unprotect(clk->core);
2018 2019
2019 if (min != clk->min_rate || max != clk->max_rate) { 2020 /* Save the current values in case we need to rollback the change */
2020 clk->min_rate = min; 2021 old_min = clk->min_rate;
2021 clk->max_rate = max; 2022 old_max = clk->max_rate;
2022 ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate); 2023 clk->min_rate = min;
2024 clk->max_rate = max;
2025
2026 rate = clk_core_get_rate_nolock(clk->core);
2027 if (rate < min || rate > max) {
2028 /*
2029 * FIXME:
2030 * We are in bit of trouble here, current rate is outside the
2031 * the requested range. We are going try to request appropriate
2032 * range boundary but there is a catch. It may fail for the
2033 * usual reason (clock broken, clock protected, etc) but also
2034 * because:
2035 * - round_rate() was not favorable and fell on the wrong
2036 * side of the boundary
2037 * - the determine_rate() callback does not really check for
2038 * this corner case when determining the rate
2039 */
2040
2041 if (rate < min)
2042 rate = min;
2043 else
2044 rate = max;
2045
2046 ret = clk_core_set_rate_nolock(clk->core, rate);
2047 if (ret) {
2048 /* rollback the changes */
2049 clk->min_rate = old_min;
2050 clk->max_rate = old_max;
2051 }
2023 } 2052 }
2024 2053
2025 if (clk->exclusive_count) 2054 if (clk->exclusive_count)