diff options
| author | Lei Wen <leiwen@marvell.com> | 2011-09-30 05:44:12 +0000 | 
|---|---|---|
| committer | Heiko Schocher <hs@denx.de> | 2011-10-03 11:50:09 +0200 | 
| commit | d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d (patch) | |
| tree | c5fdd8ec8755a96abbfe9bcad001a058be5deb98 /drivers/i2c/mv_i2c.c | |
| parent | 2be1ed349ca268d3867840fd28960785fd3def0b (diff) | |
| download | olio-uboot-2014.01-d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d.tar.xz olio-uboot-2014.01-d308c9d35aee2578d0a69a9ecb8bc7fd7df8fa2d.zip | |
I2C: mv_i2c: fix multi-bus init issue
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>
Diffstat (limited to 'drivers/i2c/mv_i2c.c')
| -rw-r--r-- | drivers/i2c/mv_i2c.c | 42 | 
1 files changed, 24 insertions, 18 deletions
| diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c index 8eb30e708..b93922bdb 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);  }  /* |