diff options
| author | Jonathan Corbet <corbet@lwn.net> | 2009-12-28 12:04:02 -0500 |
|---|---|---|
| committer | Jonathan Corbet <corbet@lwn.net> | 2010-05-07 19:17:37 -0400 |
| commit | b052d7f81fdd352a5d89ef1ac37a2c77f219463b (patch) | |
| tree | e4890ea37bfaa972ab2b481400e8183b74b6c604 | |
| parent | 7582eb9be85f35271fd2569681a88a5b243e9380 (diff) | |
via: Do not attempt I/O on inactive I2C adapters
If an adapter has been configured for GPIO (or off), we should not try to
use it as an I2C port.
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Cc: Harald Welte <laforge@gnumonks.org>
Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
| -rw-r--r-- | drivers/video/via/via_i2c.c | 14 | ||||
| -rw-r--r-- | drivers/video/via/via_i2c.h | 1 |
2 files changed, 11 insertions, 4 deletions
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 3ff60b280d88..c88450ee62ba 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c | |||
| @@ -115,6 +115,8 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) | |||
| 115 | u8 mm1[] = {0x00}; | 115 | u8 mm1[] = {0x00}; |
| 116 | struct i2c_msg msgs[2]; | 116 | struct i2c_msg msgs[2]; |
| 117 | 117 | ||
| 118 | if (!via_i2c_par[adap].is_active) | ||
| 119 | return -ENODEV; | ||
| 118 | *pdata = 0; | 120 | *pdata = 0; |
| 119 | msgs[0].flags = 0; | 121 | msgs[0].flags = 0; |
| 120 | msgs[1].flags = I2C_M_RD; | 122 | msgs[1].flags = I2C_M_RD; |
| @@ -130,6 +132,8 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) | |||
| 130 | u8 msg[2] = { index, data }; | 132 | u8 msg[2] = { index, data }; |
| 131 | struct i2c_msg msgs; | 133 | struct i2c_msg msgs; |
| 132 | 134 | ||
| 135 | if (!via_i2c_par[adap].is_active) | ||
| 136 | return -ENODEV; | ||
| 133 | msgs.flags = 0; | 137 | msgs.flags = 0; |
| 134 | msgs.addr = slave_addr / 2; | 138 | msgs.addr = slave_addr / 2; |
| 135 | msgs.len = 2; | 139 | msgs.len = 2; |
| @@ -142,6 +146,8 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len | |||
| 142 | u8 mm1[] = {0x00}; | 146 | u8 mm1[] = {0x00}; |
| 143 | struct i2c_msg msgs[2]; | 147 | struct i2c_msg msgs[2]; |
| 144 | 148 | ||
| 149 | if (!via_i2c_par[adap].is_active) | ||
| 150 | return -ENODEV; | ||
| 145 | msgs[0].flags = 0; | 151 | msgs[0].flags = 0; |
| 146 | msgs[1].flags = I2C_M_RD; | 152 | msgs[1].flags = I2C_M_RD; |
| 147 | msgs[0].addr = msgs[1].addr = slave_addr / 2; | 153 | msgs[0].addr = msgs[1].addr = slave_addr / 2; |
| @@ -198,18 +204,18 @@ static int viafb_i2c_probe(struct platform_device *platdev) | |||
| 198 | struct via_port_cfg *adap_cfg = configs++; | 204 | struct via_port_cfg *adap_cfg = configs++; |
| 199 | struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i]; | 205 | struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i]; |
| 200 | 206 | ||
| 207 | i2c_stuff->is_active = 0; | ||
| 201 | if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C) | 208 | if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C) |
| 202 | continue; | 209 | continue; |
| 203 | |||
| 204 | ret = create_i2c_bus(&i2c_stuff->adapter, | 210 | ret = create_i2c_bus(&i2c_stuff->adapter, |
| 205 | &i2c_stuff->algo, adap_cfg, | 211 | &i2c_stuff->algo, adap_cfg, |
| 206 | NULL); /* FIXME: PCIDEV */ | 212 | NULL); /* FIXME: PCIDEV */ |
| 207 | if (ret < 0) { | 213 | if (ret < 0) { |
| 208 | printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n", | 214 | printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n", |
| 209 | i, ret); | 215 | i, ret); |
| 210 | /* FIXME: properly release previous busses */ | 216 | continue; /* Still try to make the rest */ |
| 211 | return ret; | ||
| 212 | } | 217 | } |
| 218 | i2c_stuff->is_active = 1; | ||
| 213 | } | 219 | } |
| 214 | 220 | ||
| 215 | return 0; | 221 | return 0; |
| @@ -225,7 +231,7 @@ static int viafb_i2c_remove(struct platform_device *platdev) | |||
| 225 | * Only remove those entries in the array that we've | 231 | * Only remove those entries in the array that we've |
| 226 | * actually used (and thus initialized algo_data) | 232 | * actually used (and thus initialized algo_data) |
| 227 | */ | 233 | */ |
| 228 | if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) | 234 | if (i2c_stuff->is_active) |
| 229 | i2c_del_adapter(&i2c_stuff->adapter); | 235 | i2c_del_adapter(&i2c_stuff->adapter); |
| 230 | } | 236 | } |
| 231 | return 0; | 237 | return 0; |
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h index b2332cce9d18..1d18e7d57b7f 100644 --- a/drivers/video/via/via_i2c.h +++ b/drivers/video/via/via_i2c.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | struct via_i2c_stuff { | 27 | struct via_i2c_stuff { |
| 28 | u16 i2c_port; /* GPIO or I2C port */ | 28 | u16 i2c_port; /* GPIO or I2C port */ |
| 29 | u16 is_active; /* Being used as I2C? */ | ||
| 29 | struct i2c_adapter adapter; | 30 | struct i2c_adapter adapter; |
| 30 | struct i2c_algo_bit_data algo; | 31 | struct i2c_algo_bit_data algo; |
| 31 | }; | 32 | }; |
