diff options
-rw-r--r-- | drivers/clk/clk.c | 37 |
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); | |||
2000 | int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) | 2000 | int 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) |