aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorShinya Kuribayashi <shinya.kuribayashi.px@renesas.com>2012-10-24 06:56:51 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-11-16 02:57:16 -0500
commit7b0e62920ac314eb819e68b7d2c51994b98b19ca (patch)
tree65999e3a205ddde684ce5a0ef50660fd456428e2 /drivers/i2c
parent27e0fbefa5ddebdd681d2be9824302d14494c5ff (diff)
i2c: i2c-sh_mobile: calculate clock parameters at driver probing time
Currently SCL clock parameters (ICCH/ICCL) are calculated in activate_ch(), which gets called every time sh_mobile_i2c_xfer() is processed, while each I2C bus speed is system-defined and in general those parameters do not have to be updated over I2C transactions. The only reason I could see having it transaction-time is to adjust ICCH/ICCL values according to the operating frequency of the I2C hardware block, in the face of DFS (Dynamic Frequency Scaling). However, this won't be necessary. The operating frequency of the I2C hardware block can change _even_ in the middle of I2C transactions. There is no way to prevent it from happening, and I2C hardware block can work with such dynamic frequency change, of course. Another is that ICCH/ICCL clock parameters optimized for the faster operating frequency, can also be applied to the slower operating frequency, as long as slave devices work. However, the converse is not true. It would violate SCL timing specs of the I2C standard. What we can do now is to calculate the ICCH/ICCL clock parameters according to the fastest operating clock of the I2C hardware block. And if that's the case, that calculation should be done just once at driver-module-init time. This patch moves ICCH/ICCL calculating part from activate_ch() into sh_mobile_i2c_init(), and call it from sh_mobile_i2c_probe(). Note that sh_mobile_i2c_init() just prepares clock parameters using the clock rate and platform data provided, but does _not_ make any hardware I/O accesses. We don't have to care about run-time PM maintenance here. Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 8110ca45f342..309d0d592890 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -187,18 +187,15 @@ static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
187 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); 187 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
188} 188}
189 189
190static void activate_ch(struct sh_mobile_i2c_data *pd) 190static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
191{ 191{
192 unsigned long i2c_clk; 192 unsigned long i2c_clk;
193 u_int32_t num; 193 u_int32_t num;
194 u_int32_t denom; 194 u_int32_t denom;
195 u_int32_t tmp; 195 u_int32_t tmp;
196 196
197 /* Wake up device and enable clock */
198 pm_runtime_get_sync(pd->dev);
199 clk_enable(pd->clk);
200
201 /* Get clock rate after clock is enabled */ 197 /* Get clock rate after clock is enabled */
198 clk_enable(pd->clk);
202 i2c_clk = clk_get_rate(pd->clk); 199 i2c_clk = clk_get_rate(pd->clk);
203 200
204 /* Calculate the value for iccl. From the data sheet: 201 /* Calculate the value for iccl. From the data sheet:
@@ -239,6 +236,15 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
239 pd->icic &= ~ICIC_ICCHB8; 236 pd->icic &= ~ICIC_ICCHB8;
240 } 237 }
241 238
239 clk_disable(pd->clk);
240}
241
242static void activate_ch(struct sh_mobile_i2c_data *pd)
243{
244 /* Wake up device and enable clock */
245 pm_runtime_get_sync(pd->dev);
246 clk_enable(pd->clk);
247
242 /* Enable channel and configure rx ack */ 248 /* Enable channel and configure rx ack */
243 iic_set_clr(pd, ICCR, ICCR_ICE, 0); 249 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
244 250
@@ -632,6 +638,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
632 if (size > 0x17) 638 if (size > 0x17)
633 pd->flags |= IIC_FLAG_HAS_ICIC67; 639 pd->flags |= IIC_FLAG_HAS_ICIC67;
634 640
641 sh_mobile_i2c_init(pd);
642
635 /* Enable Runtime PM for this device. 643 /* Enable Runtime PM for this device.
636 * 644 *
637 * Also tell the Runtime PM core to ignore children 645 * Also tell the Runtime PM core to ignore children