aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-09-12 08:36:45 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-09-30 00:02:32 -0400
commit8d0494037bb2af32a22563d40703c1263fca318d (patch)
tree27b4c422a5c7f38b7da661648c81babec81ba9a2
parent14d32f1794fd559e12f27e8b5c57053073bd75aa (diff)
i2c: rcar: get clock rate only once and simplify calculation
There is no need to repeatedly query clock frequency, where it is not expected to change. The complete loop can also trivially be replaced with a simple division. A further loop below the one, being simplified, could also be replaced, but that would get more complicated. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-rcar.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 15eef94927e7..9325db49b4df 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -231,6 +231,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
231 u32 round, ick; 231 u32 round, ick;
232 u32 scl; 232 u32 scl;
233 u32 cdf_width; 233 u32 cdf_width;
234 unsigned long rate;
234 235
235 if (!clkp) { 236 if (!clkp) {
236 dev_err(dev, "there is no peripheral_clk\n"); 237 dev_err(dev, "there is no peripheral_clk\n");
@@ -264,15 +265,14 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
264 * clkp : peripheral_clk 265 * clkp : peripheral_clk
265 * F[] : integer up-valuation 266 * F[] : integer up-valuation
266 */ 267 */
267 for (cdf = 0; cdf < (1 << cdf_width); cdf++) { 268 rate = clk_get_rate(clkp);
268 ick = clk_get_rate(clkp) / (1 + cdf); 269 cdf = rate / 20000000;
269 if (ick < 20000000) 270 if (cdf >= 1 << cdf_width) {
270 goto ick_find; 271 dev_err(dev, "Input clock %lu too high\n", rate);
272 return -EIO;
271 } 273 }
272 dev_err(dev, "there is no best CDF\n"); 274 ick = rate / (cdf + 1);
273 return -EIO;
274 275
275ick_find:
276 /* 276 /*
277 * it is impossible to calculate large scale 277 * it is impossible to calculate large scale
278 * number on u32. separate it 278 * number on u32. separate it
@@ -290,6 +290,12 @@ ick_find:
290 * 290 *
291 * Calculation result (= SCL) should be less than 291 * Calculation result (= SCL) should be less than
292 * bus_speed for hardware safety 292 * bus_speed for hardware safety
293 *
294 * We could use something along the lines of
295 * div = ick / (bus_speed + 1) + 1;
296 * scgd = (div - 20 - round + 7) / 8;
297 * scl = ick / (20 + (scgd * 8) + round);
298 * (not fully verified) but that would get pretty involved
293 */ 299 */
294 for (scgd = 0; scgd < 0x40; scgd++) { 300 for (scgd = 0; scgd < 0x40; scgd++) {
295 scl = ick / (20 + (scgd * 8) + round); 301 scl = ick / (20 + (scgd * 8) + round);