From 85c5702ac046b14713f776d59768252d8ed8018f Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 17 Sep 2010 01:16:25 +0000 Subject: viafb: fix i2c_transfer error handling i2c_transfer returns negative errno on error and number of messages processed on success. Just returning this value would give a poor interface as it is not obvious that you must compare with 2 after reading 1 or n bytes and with 1 after writing 1 byte to determine if it was successful. To avoid this error prone interface convert the error code of a successful read/write to zero and all other non-negative values to an negative error code. This fixes a regression introduced by via: Rationalize vt1636 detection which resulted in no longer detecting a VT1636 chip and therefore has broken the output in configurations which contain this chip. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: stable@kernel.org --- drivers/video/via/via_i2c.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers/video/via/via_i2c.c') diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index da9e4ca94b17..021112e279de 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -114,6 +114,7 @@ static void via_i2c_setsda(void *data, int state) int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -126,11 +127,18 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) mm1[0] = index; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = pdata; - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) { + int ret; u8 msg[2] = { index, data }; struct i2c_msg msgs; @@ -140,11 +148,18 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) msgs.addr = slave_addr / 2; msgs.len = 2; msgs.buf = msg; - return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); + ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); + if (ret == 1) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -156,7 +171,13 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len mm1[0] = index; msgs[0].len = 1; msgs[1].len = buff_len; msgs[0].buf = mm1; msgs[1].buf = buff; - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } /* -- cgit v1.2.3 From e029ab0d02b94d633d8e82a46dfdb7fd94a62216 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 17 Sep 2010 02:10:33 +0000 Subject: viafb: reduce I2C timeout and delay This patch reduces the value for I2C timeout and udelay. The udelay was reduced to 10 (old: 40) which is still very high as for standard-mode I2C even 5 should work. This gives a speedup of factor 4 when talking to I2C devices. The timeout was reduced to 2 (old: 20) which is taken from the radeon driver so it should work as well. This gives a speedup of factor 10 when detecting that there is no I2C device we want to talk to. This causes a huge improvement of device initialization time. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/via_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video/via/via_i2c.c') diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 021112e279de..3844b558b7bd 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -202,8 +202,8 @@ static int create_i2c_bus(struct i2c_adapter *adapter, algo->setscl = via_i2c_setscl; algo->getsda = via_i2c_getsda; algo->getscl = via_i2c_getscl; - algo->udelay = 40; - algo->timeout = 20; + algo->udelay = 10; + algo->timeout = 2; algo->data = adap_cfg; sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", -- cgit v1.2.3