diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-30 17:50:44 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-30 17:50:44 -0500 |
| commit | af5fdf80645304e7077ab876a43b325425c7ef70 (patch) | |
| tree | f832bcdc45c60a7858b64f0a340cd10934c3eb9f | |
| parent | 07a6d5a49c985ae6111221b93b3a48772cc4b976 (diff) | |
| parent | 4d29196c535088e807061ce2a0aa526daec2edfb (diff) | |
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
at24: Use timeout also for read
i2c: Fix userspace_device list corruption
MAINTAINERS: Add missing i2c files
i2c/tsl2550: Fix lux value in extended mode
| -rw-r--r-- | MAINTAINERS | 3 | ||||
| -rw-r--r-- | drivers/i2c/chips/tsl2550.c | 3 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 11 | ||||
| -rw-r--r-- | drivers/misc/eeprom/at24.c | 76 |
4 files changed, 60 insertions, 33 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c385456caaf0..16129e67678a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2562,8 +2562,7 @@ S: Maintained | |||
| 2562 | F: Documentation/i2c/ | 2562 | F: Documentation/i2c/ |
| 2563 | F: drivers/i2c/ | 2563 | F: drivers/i2c/ |
| 2564 | F: include/linux/i2c.h | 2564 | F: include/linux/i2c.h |
| 2565 | F: include/linux/i2c-dev.h | 2565 | F: include/linux/i2c-*.h |
| 2566 | F: include/linux/i2c-id.h | ||
| 2567 | 2566 | ||
| 2568 | I2C-TINY-USB DRIVER | 2567 | I2C-TINY-USB DRIVER |
| 2569 | M: Till Harbaum <till@harbaum.org> | 2568 | M: Till Harbaum <till@harbaum.org> |
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index aa96bd2d27ea..a0702f36a72f 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
| @@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, | |||
| 257 | 257 | ||
| 258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | 258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) |
| 259 | { | 259 | { |
| 260 | struct tsl2550_data *data = i2c_get_clientdata(client); | ||
| 260 | u8 ch0, ch1; | 261 | u8 ch0, ch1; |
| 261 | int ret; | 262 | int ret; |
| 262 | 263 | ||
| @@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | |||
| 274 | ret = tsl2550_calculate_lux(ch0, ch1); | 275 | ret = tsl2550_calculate_lux(ch0, ch1); |
| 275 | if (ret < 0) | 276 | if (ret < 0) |
| 276 | return ret; | 277 | return ret; |
| 278 | if (data->operating_mode == 1) | ||
| 279 | ret *= 5; | ||
| 277 | 280 | ||
| 278 | return sprintf(buf, "%d\n", ret); | 281 | return sprintf(buf, "%d\n", ret); |
| 279 | } | 282 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 8d80fceca6a4..296504355142 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
| 762 | { | 762 | { |
| 763 | int res = 0; | 763 | int res = 0; |
| 764 | struct i2c_adapter *found; | 764 | struct i2c_adapter *found; |
| 765 | struct i2c_client *client, *next; | ||
| 765 | 766 | ||
| 766 | /* First make sure that this adapter was ever added */ | 767 | /* First make sure that this adapter was ever added */ |
| 767 | mutex_lock(&core_lock); | 768 | mutex_lock(&core_lock); |
| @@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
| 781 | if (res) | 782 | if (res) |
| 782 | return res; | 783 | return res; |
| 783 | 784 | ||
| 785 | /* Remove devices instantiated from sysfs */ | ||
| 786 | list_for_each_entry_safe(client, next, &userspace_devices, detected) { | ||
| 787 | if (client->adapter == adap) { | ||
| 788 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", | ||
| 789 | client->name, client->addr); | ||
| 790 | list_del(&client->detected); | ||
| 791 | i2c_unregister_device(client); | ||
| 792 | } | ||
| 793 | } | ||
| 794 | |||
| 784 | /* Detach any active clients. This can't fail, thus we do not | 795 | /* Detach any active clients. This can't fail, thus we do not |
| 785 | checking the returned value. */ | 796 | checking the returned value. */ |
| 786 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); | 797 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index db39f4a52f53..2cb2736d65aa 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
| @@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
| 158 | struct i2c_msg msg[2]; | 158 | struct i2c_msg msg[2]; |
| 159 | u8 msgbuf[2]; | 159 | u8 msgbuf[2]; |
| 160 | struct i2c_client *client; | 160 | struct i2c_client *client; |
| 161 | unsigned long timeout, read_time; | ||
| 161 | int status, i; | 162 | int status, i; |
| 162 | 163 | ||
| 163 | memset(msg, 0, sizeof(msg)); | 164 | memset(msg, 0, sizeof(msg)); |
| @@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
| 183 | if (count > io_limit) | 184 | if (count > io_limit) |
| 184 | count = io_limit; | 185 | count = io_limit; |
| 185 | 186 | ||
| 186 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
| 187 | if (at24->use_smbus) { | 187 | if (at24->use_smbus) { |
| 188 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
| 188 | if (count > I2C_SMBUS_BLOCK_MAX) | 189 | if (count > I2C_SMBUS_BLOCK_MAX) |
| 189 | count = I2C_SMBUS_BLOCK_MAX; | 190 | count = I2C_SMBUS_BLOCK_MAX; |
| 190 | status = i2c_smbus_read_i2c_block_data(client, offset, | 191 | } else { |
| 191 | count, buf); | 192 | /* |
| 192 | dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n", | 193 | * When we have a better choice than SMBus calls, use a |
| 193 | count, offset, status); | 194 | * combined I2C message. Write address; then read up to |
| 194 | return (status < 0) ? -EIO : status; | 195 | * io_limit data bytes. Note that read page rollover helps us |
| 196 | * here (unlike writes). msgbuf is u8 and will cast to our | ||
| 197 | * needs. | ||
| 198 | */ | ||
| 199 | i = 0; | ||
| 200 | if (at24->chip.flags & AT24_FLAG_ADDR16) | ||
| 201 | msgbuf[i++] = offset >> 8; | ||
| 202 | msgbuf[i++] = offset; | ||
| 203 | |||
| 204 | msg[0].addr = client->addr; | ||
| 205 | msg[0].buf = msgbuf; | ||
| 206 | msg[0].len = i; | ||
| 207 | |||
| 208 | msg[1].addr = client->addr; | ||
| 209 | msg[1].flags = I2C_M_RD; | ||
| 210 | msg[1].buf = buf; | ||
| 211 | msg[1].len = count; | ||
| 195 | } | 212 | } |
| 196 | 213 | ||
| 197 | /* | 214 | /* |
| 198 | * When we have a better choice than SMBus calls, use a combined | 215 | * Reads fail if the previous write didn't complete yet. We may |
| 199 | * I2C message. Write address; then read up to io_limit data bytes. | 216 | * loop a few times until this one succeeds, waiting at least |
| 200 | * Note that read page rollover helps us here (unlike writes). | 217 | * long enough for one entire page write to work. |
| 201 | * msgbuf is u8 and will cast to our needs. | ||
| 202 | */ | 218 | */ |
| 203 | i = 0; | 219 | timeout = jiffies + msecs_to_jiffies(write_timeout); |
| 204 | if (at24->chip.flags & AT24_FLAG_ADDR16) | 220 | do { |
| 205 | msgbuf[i++] = offset >> 8; | 221 | read_time = jiffies; |
| 206 | msgbuf[i++] = offset; | 222 | if (at24->use_smbus) { |
| 207 | 223 | status = i2c_smbus_read_i2c_block_data(client, offset, | |
| 208 | msg[0].addr = client->addr; | 224 | count, buf); |
| 209 | msg[0].buf = msgbuf; | 225 | } else { |
| 210 | msg[0].len = i; | 226 | status = i2c_transfer(client->adapter, msg, 2); |
| 227 | if (status == 2) | ||
| 228 | status = count; | ||
| 229 | } | ||
| 230 | dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", | ||
| 231 | count, offset, status, jiffies); | ||
| 211 | 232 | ||
| 212 | msg[1].addr = client->addr; | 233 | if (status == count) |
| 213 | msg[1].flags = I2C_M_RD; | 234 | return count; |
| 214 | msg[1].buf = buf; | ||
| 215 | msg[1].len = count; | ||
| 216 | 235 | ||
| 217 | status = i2c_transfer(client->adapter, msg, 2); | 236 | /* REVISIT: at HZ=100, this is sloooow */ |
| 218 | dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n", | 237 | msleep(1); |
| 219 | count, offset, status); | 238 | } while (time_before(read_time, timeout)); |
| 220 | 239 | ||
| 221 | if (status == 2) | 240 | return -ETIMEDOUT; |
| 222 | return count; | ||
| 223 | else if (status >= 0) | ||
| 224 | return -EIO; | ||
| 225 | else | ||
| 226 | return status; | ||
| 227 | } | 241 | } |
| 228 | 242 | ||
| 229 | static ssize_t at24_read(struct at24_data *at24, | 243 | static ssize_t at24_read(struct at24_data *at24, |
