]>
Commit | Line | Data |
---|---|---|
ad522180 GKH |
1 | From 85c5702ac046b14713f776d59768252d8ed8018f Mon Sep 17 00:00:00 2001 |
2 | From: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | |
3 | Date: Fri, 17 Sep 2010 01:16:25 +0000 | |
4 | Subject: viafb: fix i2c_transfer error handling | |
5 | ||
6 | From: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | |
7 | ||
8 | commit 85c5702ac046b14713f776d59768252d8ed8018f upstream. | |
9 | ||
10 | i2c_transfer returns negative errno on error and number of messages | |
11 | processed on success. Just returning this value would give a poor | |
12 | interface as it is not obvious that you must compare with 2 after reading | |
13 | 1 or n bytes and with 1 after writing 1 byte to determine if it was | |
14 | successful. To avoid this error prone interface convert the error code | |
15 | of a successful read/write to zero and all other non-negative values to | |
16 | an negative error code. | |
17 | This fixes a regression introduced by | |
18 | via: Rationalize vt1636 detection | |
19 | which resulted in no longer detecting a VT1636 chip and therefore has | |
20 | broken the output in configurations which contain this chip. | |
21 | ||
22 | Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | |
23 | Acked-by: Jonathan Corbet <corbet@lwn.net> | |
24 | Cc: Joseph Chan <JosephChan@via.com.tw> | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
26 | ||
27 | --- | |
28 | drivers/video/via/via_i2c.c | 27 ++++++++++++++++++++++++--- | |
29 | 1 file changed, 24 insertions(+), 3 deletions(-) | |
30 | ||
31 | --- a/drivers/video/via/via_i2c.c | |
32 | +++ b/drivers/video/via/via_i2c.c | |
33 | @@ -114,6 +114,7 @@ static void via_i2c_setsda(void *data, i | |
34 | ||
35 | int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) | |
36 | { | |
37 | + int ret; | |
38 | u8 mm1[] = {0x00}; | |
39 | struct i2c_msg msgs[2]; | |
40 | ||
41 | @@ -126,11 +127,18 @@ int viafb_i2c_readbyte(u8 adap, u8 slave | |
42 | mm1[0] = index; | |
43 | msgs[0].len = 1; msgs[1].len = 1; | |
44 | msgs[0].buf = mm1; msgs[1].buf = pdata; | |
45 | - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); | |
46 | + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); | |
47 | + if (ret == 2) | |
48 | + ret = 0; | |
49 | + else if (ret >= 0) | |
50 | + ret = -EIO; | |
51 | + | |
52 | + return ret; | |
53 | } | |
54 | ||
55 | int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) | |
56 | { | |
57 | + int ret; | |
58 | u8 msg[2] = { index, data }; | |
59 | struct i2c_msg msgs; | |
60 | ||
61 | @@ -140,11 +148,18 @@ int viafb_i2c_writebyte(u8 adap, u8 slav | |
62 | msgs.addr = slave_addr / 2; | |
63 | msgs.len = 2; | |
64 | msgs.buf = msg; | |
65 | - return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); | |
66 | + ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); | |
67 | + if (ret == 1) | |
68 | + ret = 0; | |
69 | + else if (ret >= 0) | |
70 | + ret = -EIO; | |
71 | + | |
72 | + return ret; | |
73 | } | |
74 | ||
75 | int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) | |
76 | { | |
77 | + int ret; | |
78 | u8 mm1[] = {0x00}; | |
79 | struct i2c_msg msgs[2]; | |
80 | ||
81 | @@ -156,7 +171,13 @@ int viafb_i2c_readbytes(u8 adap, u8 slav | |
82 | mm1[0] = index; | |
83 | msgs[0].len = 1; msgs[1].len = buff_len; | |
84 | msgs[0].buf = mm1; msgs[1].buf = buff; | |
85 | - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); | |
86 | + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); | |
87 | + if (ret == 2) | |
88 | + ret = 0; | |
89 | + else if (ret >= 0) | |
90 | + ret = -EIO; | |
91 | + | |
92 | + return ret; | |
93 | } | |
94 | ||
95 | /* |