mirror of https://gitee.com/openkylin/linux.git
[PATCH] i2c-iop3xx: Avoid addressing self
Avoid addressing self when sending a slave address. Follows instruction in Intel 80331/80321 manuals. Ignoring this worked previously on 80321, but causes a hang on i2cdetect on 80331. Signed-off-by: Peter Milne <peter.milne@d-tacq.com> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
2369df933f
commit
39288e1ac1
|
@ -21,6 +21,9 @@
|
||||||
* - Make it work with IXP46x chips
|
* - Make it work with IXP46x chips
|
||||||
* - Cleanup function names, coding style, etc
|
* - Cleanup function names, coding style, etc
|
||||||
*
|
*
|
||||||
|
* - writing to slave address causes latchup on iop331.
|
||||||
|
* fix: driver refuses to address self.
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 2.
|
* the Free Software Foundation, version 2.
|
||||||
|
@ -72,12 +75,6 @@ iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
|
||||||
__raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
|
__raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
iop3xx_i2c_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
|
|
||||||
{
|
|
||||||
__raw_writel(MYSAR, iop3xx_adap->ioaddr + SAR_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
|
iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
|
||||||
{
|
{
|
||||||
|
@ -248,6 +245,13 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
|
||||||
int status;
|
int status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* avoid writing to my slave address (hangs on 80331),
|
||||||
|
* forbidden in Intel developer manual
|
||||||
|
*/
|
||||||
|
if (msg->addr == MYSAR) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
__raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
|
__raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
|
||||||
|
|
||||||
cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
|
cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
|
||||||
|
@ -498,7 +502,6 @@ iop3xx_i2c_probe(struct platform_device *pdev)
|
||||||
spin_lock_init(&adapter_data->lock);
|
spin_lock_init(&adapter_data->lock);
|
||||||
|
|
||||||
iop3xx_i2c_reset(adapter_data);
|
iop3xx_i2c_reset(adapter_data);
|
||||||
iop3xx_i2c_set_slave_addr(adapter_data);
|
|
||||||
iop3xx_i2c_enable(adapter_data);
|
iop3xx_i2c_enable(adapter_data);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, new_adapter);
|
platform_set_drvdata(pdev, new_adapter);
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
#define IOP3XX_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */
|
#define IOP3XX_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */
|
||||||
#define IOP3XX_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */
|
#define IOP3XX_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */
|
||||||
|
|
||||||
#define MYSAR 0x02 /* SWAG a suitable slave address */
|
#define MYSAR 0 /* default slave address */
|
||||||
|
|
||||||
#define I2C_ERR 321
|
#define I2C_ERR 321
|
||||||
#define I2C_ERR_BERR (I2C_ERR+0)
|
#define I2C_ERR_BERR (I2C_ERR+0)
|
||||||
|
|
Loading…
Reference in New Issue