diff options
author | Tomasz Figa <tomasz.figa@gmail.com> | 2014-01-11 16:39:04 -0500 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-03-03 10:23:32 -0500 |
commit | 222a13c5d0c67333e443a1ea2fcc746ad61f8d68 (patch) | |
tree | 0be436987c782fb63333952c2ca2a1a305b7fa84 /drivers/mmc | |
parent | 8f4b78d9bb042aacce43e0213c727da861a128f6 (diff) |
mmc: sdhci-s3c: Simplify min/max clock calculation
This patch reimplements functions calculating minimum and maximum clock
rates to leverage clock rate cache introduced by previous patches.
In addition, the calculation is simplified to just comparing input
clock rates (max case) or input clock rates divided by maximum divisor
(min case), which is basically what the original code did, but with much
more unnecessary work.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
Acked-by; Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci-s3c.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 7fde938facb0..7e14db07eb30 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -112,20 +112,16 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host) | |||
112 | static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) | 112 | static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) |
113 | { | 113 | { |
114 | struct sdhci_s3c *ourhost = to_s3c(host); | 114 | struct sdhci_s3c *ourhost = to_s3c(host); |
115 | struct clk *busclk; | 115 | unsigned long rate, max = 0; |
116 | unsigned int rate, max; | 116 | int src; |
117 | int clk; | ||
118 | 117 | ||
119 | /* note, a reset will reset the clock source */ | 118 | /* note, a reset will reset the clock source */ |
120 | 119 | ||
121 | sdhci_s3c_check_sclk(host); | 120 | sdhci_s3c_check_sclk(host); |
122 | 121 | ||
123 | for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) { | ||
124 | busclk = ourhost->clk_bus[clk]; | ||
125 | if (!busclk) | ||
126 | continue; | ||
127 | 122 | ||
128 | rate = clk_get_rate(busclk); | 123 | for (src = 0; src < MAX_BUS_CLK; src++) { |
124 | rate = ourhost->clk_rates[src]; | ||
129 | if (rate > max) | 125 | if (rate > max) |
130 | max = rate; | 126 | max = rate; |
131 | } | 127 | } |
@@ -255,17 +251,17 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) | |||
255 | static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) | 251 | static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) |
256 | { | 252 | { |
257 | struct sdhci_s3c *ourhost = to_s3c(host); | 253 | struct sdhci_s3c *ourhost = to_s3c(host); |
258 | unsigned int delta, min = UINT_MAX; | 254 | unsigned long rate, min = ULONG_MAX; |
259 | int src; | 255 | int src; |
260 | 256 | ||
261 | for (src = 0; src < MAX_BUS_CLK; src++) { | 257 | for (src = 0; src < MAX_BUS_CLK; src++) { |
262 | delta = sdhci_s3c_consider_clock(ourhost, src, 0); | 258 | rate = ourhost->clk_rates[src] / 256; |
263 | if (delta == UINT_MAX) | 259 | if (!rate) |
264 | continue; | 260 | continue; |
265 | /* delta is a negative value in this case */ | 261 | if (rate < min) |
266 | if (-delta < min) | 262 | min = rate; |
267 | min = -delta; | ||
268 | } | 263 | } |
264 | |||
269 | return min; | 265 | return min; |
270 | } | 266 | } |
271 | 267 | ||
@@ -273,20 +269,44 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) | |||
273 | static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) | 269 | static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) |
274 | { | 270 | { |
275 | struct sdhci_s3c *ourhost = to_s3c(host); | 271 | struct sdhci_s3c *ourhost = to_s3c(host); |
272 | unsigned long rate, max = 0; | ||
273 | int src; | ||
274 | |||
275 | for (src = 0; src < MAX_BUS_CLK; src++) { | ||
276 | struct clk *clk; | ||
277 | |||
278 | clk = ourhost->clk_bus[src]; | ||
279 | if (IS_ERR(clk)) | ||
280 | continue; | ||
281 | |||
282 | rate = clk_round_rate(clk, ULONG_MAX); | ||
283 | if (rate > max) | ||
284 | max = rate; | ||
285 | } | ||
276 | 286 | ||
277 | return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX); | 287 | return max; |
278 | } | 288 | } |
279 | 289 | ||
280 | /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ | 290 | /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ |
281 | static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) | 291 | static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) |
282 | { | 292 | { |
283 | struct sdhci_s3c *ourhost = to_s3c(host); | 293 | struct sdhci_s3c *ourhost = to_s3c(host); |
294 | unsigned long rate, min = ULONG_MAX; | ||
295 | int src; | ||
284 | 296 | ||
285 | /* | 297 | for (src = 0; src < MAX_BUS_CLK; src++) { |
286 | * initial clock can be in the frequency range of | 298 | struct clk *clk; |
287 | * 100KHz-400KHz, so we set it as max value. | 299 | |
288 | */ | 300 | clk = ourhost->clk_bus[src]; |
289 | return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], 400000); | 301 | if (IS_ERR(clk)) |
302 | continue; | ||
303 | |||
304 | rate = clk_round_rate(clk, 0); | ||
305 | if (rate < min) | ||
306 | min = rate; | ||
307 | } | ||
308 | |||
309 | return min; | ||
290 | } | 310 | } |
291 | 311 | ||
292 | /* sdhci_cmu_set_clock - callback on clock change.*/ | 312 | /* sdhci_cmu_set_clock - callback on clock change.*/ |