[U-Boot] [PATCH 14/24] mxc_i2c: add retries

Marek Vasut marex at denx.de
Fri Jun 22 19:06:03 CEST 2012


Dear Troy Kisky,

> Retry unexpected hardware errors. This
> will not retry a received NAK.
> 
> Signed-off-by: Troy Kisky <troy.kisky at boundarydevices.com>

Why do you need this? Are you getting transmission errors? I think it's because 
you broke something in the driver, I was getting errors, but managed to hack it 
together in such a manner, that they didn't happen anymore.

> ---
>  drivers/i2c/mxc_i2c.c |   36 +++++++++++++++++++++++++++---------
>  1 file changed, 27 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> index df033ea..802f70f 100644
> --- a/drivers/i2c/mxc_i2c.c
> +++ b/drivers/i2c/mxc_i2c.c
> @@ -213,7 +213,7 @@ void i2c_imx_stop(void)
>   * Send start signal, chip address and
>   * write register address
>   */
> -static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
> +static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs,
>  		uchar chip, uint addr, int alen)
>  {
>  	unsigned int temp;
> @@ -230,7 +230,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs
> *i2c_regs, writeb(0, &i2c_regs->i2sr);
>  	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
>  	if (ret < 0)
> -		goto exit;
> +		return ret;
> 
>  	/* Start I2C transaction */
>  	temp = readb(&i2c_regs->i2cr);
> @@ -239,7 +239,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs
> *i2c_regs,
> 
>  	ret = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
>  	if (ret < 0)
> -		goto exit;
> +		return ret;
> 
>  	temp |= I2CR_MTX | I2CR_TX_NO_AK;
>  	writeb(temp, &i2c_regs->i2cr);
> @@ -247,18 +247,36 @@ static int i2c_init_transfer(struct mxc_i2c_regs
> *i2c_regs, /* write slave address */
>  	ret = tx_byte(i2c_regs, chip << 1);
>  	if (ret < 0)
> -		goto exit;
> +		return ret;
> 
>  	while (alen--) {
>  		ret =  tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff);
>  		if (ret < 0)
> -			goto exit;
> +			return ret;
>  	}
>  	return 0;
> -exit:
> -	i2c_imx_stop();
> -	/* Disable I2C controller */
> -	writeb(0, &i2c_regs->i2cr);
> +}
> +
> +static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
> +		uchar chip, uint addr, int alen)
> +{
> +	int retry;
> +	int ret;
> +	for (retry = 0; retry < 3; retry++) {
> +		ret = i2c_init_transfer_(i2c_regs, chip, addr, alen);
> +		if (ret >= 0)
> +			return ret;
> +		i2c_imx_stop(i2c_regs);
> +		if (ret == -ENODEV)
> +			return ret;
> +
> +		printf("%s: failed for chip 0x%x retry=%d\n", __func__, chip,
> +				retry);
> +		if (ret != -ERESTART)
> +			writeb(0, &i2c_regs->i2cr);	/* Disable controller */
> +		udelay(100);
> +	}
> +	printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs);
>  	return ret;
>  }

Best regards,
Marek Vasut


More information about the U-Boot mailing list