[i2c] [patch 2.6.24-rc1-git] i2c-algo-bit, don't yield()
David Brownell
david-b at pacbell.net
Thu Nov 15 09:43:32 CET 2007
On Tuesday 06 November 2007, Jean Delvare wrote:
> This automatic retry thing is misimplemented in at least
> two bus drivers, and causes delays for everyone (e.g. when framebuffer
> drivers probe for EDID EEPROMs). That's enough harm to warrant a swift
> removal. If anybody really cares, we'll discuss the matter with them
> when they complain.
OK ... here's a patch removing it from i2c-algo-bit
(and thence its users).
- Dave
=============
Remove the "retry address stage" mechanism from i2c-algo-bit. That
mechanism is not something that upper level code can rely on; hardly
any I2C adapter drivers implement it, much less do it correctly.
Plus the notion itself is dubious.
Return any actual fault code returned in preferece to -EREMOTEIO, when
trying to address a specific device.
Signed-off-by: David Brownell <dbrownell at users.sourceforge.net>
---
drivers/i2c/algos/i2c-algo-bit.c | 54 ++++++++++++---------------------------
1 files changed, 17 insertions(+), 37 deletions(-)
--- a/drivers/i2c/algos/i2c-algo-bit.c 2007-11-14 21:36:34.000000000 -0800
+++ b/drivers/i2c/algos/i2c-algo-bit.c 2007-11-14 21:36:34.000000000 -0800
@@ -309,36 +309,17 @@ bailout:
/* ----- Utility functions
*/
-/* try_address tries to contact a chip for a number of
- * times before it gives up.
+/* try_address tries to contact a chip. SMBus devices are required
+ * to respond; I2C devices don't need to, if they're too busy.
+ *
* return values:
* 1 chip answered
* 0 chip did not answer
- * -x transmission error
+ * -x transmission error (or lost arbitration)
*/
-static int try_address(struct i2c_adapter *i2c_adap,
- unsigned char addr, int retries)
+static int try_address(struct i2c_adapter *i2c_adap, unsigned char addr)
{
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- int i, ret = -1;
-
- for (i = 0; i <= retries; i++) {
- ret = i2c_outb(i2c_adap, addr);
- if (ret == 1 || i == retries)
- break;
- bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
- i2c_stop(adap);
- udelay(adap->udelay);
- yield();
- bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
- i2c_start(adap);
- }
- if (i && ret)
- bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
- "0x%02x: %s\n", i + 1,
- addr & 1 ? "read from" : "write to", addr >> 1,
- ret == 1 ? "success" : "failed, timeout?");
- return ret;
+ return i2c_outb(i2c_adap, addr);
}
static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
@@ -465,27 +446,25 @@ static int bit_doAddress(struct i2c_adap
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
unsigned char addr;
- int ret, retries;
-
- retries = nak_ok ? 0 : i2c_adap->retries;
+ int ret;
if (flags & I2C_M_TEN) {
/* a ten bit address */
addr = 0xf0 | ((msg->addr >> 7) & 0x03);
bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
/* try extended address code...*/
- ret = try_address(i2c_adap, addr, retries);
+ ret = try_address(i2c_adap, addr);
if ((ret != 1) && !nak_ok) {
dev_err(&i2c_adap->dev,
"died at extended address code\n");
- return -EREMOTEIO;
+ goto fail;
}
/* the remaining 8 bit address */
ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
if ((ret != 1) && !nak_ok) {
/* the chip did not ack / xmission error occurred */
dev_err(&i2c_adap->dev, "died at 2nd address code\n");
- return -EREMOTEIO;
+ goto fail;
}
if (flags & I2C_M_RD) {
bit_dbg(3, &i2c_adap->dev, "emitting repeated "
@@ -493,11 +472,11 @@ static int bit_doAddress(struct i2c_adap
i2c_repstart(adap);
/* okay, now switch into reading mode */
addr |= 0x01;
- ret = try_address(i2c_adap, addr, retries);
+ ret = try_address(i2c_adap, addr);
if ((ret != 1) && !nak_ok) {
dev_err(&i2c_adap->dev,
"died at repeated address code\n");
- return -EREMOTEIO;
+ goto fail;
}
}
} else { /* normal 7bit address */
@@ -506,12 +485,14 @@ static int bit_doAddress(struct i2c_adap
addr |= 1;
if (flags & I2C_M_REV_DIR_ADDR)
addr ^= 1;
- ret = try_address(i2c_adap, addr, retries);
+ ret = try_address(i2c_adap, addr);
if ((ret != 1) && !nak_ok)
- return -EREMOTEIO;
+ goto fail;
}
return 0;
+fail:
+ return (ret < 0) ? ret : -EREMOTEIO;
}
static int bit_xfer(struct i2c_adapter *i2c_adap,
@@ -605,8 +586,7 @@ static int i2c_bit_prepare_bus(struct i2
/* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo;
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
+ adap->timeout = 100; /* default value */
return 0;
}
More information about the i2c
mailing list