Patchwork [U-Boot] I2C: mv_i2c: fix multi-bus init issue

login
register
mail settings
Submitter Lei Wen
Date Sept. 30, 2011, 3:44 p.m.
Message ID <1317397452-4141-1-git-send-email-leiwen@marvell.com>
Download mbox | patch
Permalink /patch/117163/
State Accepted
Commit d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d
Delegated to: Heiko Schocher
Headers show

Comments

Lei Wen - Sept. 30, 2011, 3:44 p.m.
When enable the multi-bus, the current_bus is not inited in the original
implementation, which make the i2c operation unpredicatable.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 drivers/i2c/mv_i2c.c |   42 ++++++++++++++++++++++++------------------
 1 files changed, 24 insertions(+), 18 deletions(-)
Heiko Schocher - Oct. 3, 2011, 9:56 a.m.
Hello Lei,

Lei Wen wrote:
> When enable the multi-bus, the current_bus is not inited in the original
> implementation, which make the i2c operation unpredicatable.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  drivers/i2c/mv_i2c.c |   42 ++++++++++++++++++++++++------------------
>  1 files changed, 24 insertions(+), 18 deletions(-)

Applied to u-boot-i2c.git

Thanks!

bye,
Heiko

Patch

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 8eb30e7..729c60a 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -67,6 +67,27 @@  struct mv_i2c {
 };
 
 static struct mv_i2c *base;
+static void i2c_board_init(struct mv_i2c *base)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
+	/*
+	 * call board specific i2c bus reset routine before accessing the
+	 * environment, which might be in a chip on that bus. For details
+	 * about this problem see doc/I2C_Edge_Conditions.
+	 *
+	 * disable I2C controller first, otherwhise it thinks we want to
+	 * talk to the slave port...
+	 */
+	icr = readl(&base->icr);
+	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
+
+	i2c_init_board();
+
+	writel(icr, &base->icr);
+#endif
+}
+
 #ifdef CONFIG_I2C_MULTI_BUS
 static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
 static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
@@ -83,7 +104,7 @@  int i2c_set_bus_num(unsigned int bus)
 	current_bus = bus;
 
 	if (!bus_initialized[current_bus]) {
-		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		i2c_board_init(base);
 		bus_initialized[current_bus] = 1;
 	}
 
@@ -264,28 +285,13 @@  i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_I2C_MULTI_BUS
+	current_bus = 0;
 	base = (struct mv_i2c *)i2c_regs[current_bus];
 #else
 	base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
 #endif
 
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	u32 icr;
-	/*
-	 * call board specific i2c bus reset routine before accessing the
-	 * environment, which might be in a chip on that bus. For details
-	 * about this problem see doc/I2C_Edge_Conditions.
-	 *
-	 * disable I2C controller first, otherwhise it thinks we want to
-	 * talk to the slave port...
-	 */
-	icr = readl(&base->icr);
-	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
-
-	i2c_init_board();
-
-	writel(icr, &base->icr);
-#endif
+	i2c_board_init(base);
 }
 
 /*