diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
| -rw-r--r-- | drivers/i2c/i2c-core.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 9cb277d6aa48..01233f0f7771 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -183,15 +183,21 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
| 183 | sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); | 183 | sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); |
| 184 | adap->dev.driver = &i2c_adapter_driver; | 184 | adap->dev.driver = &i2c_adapter_driver; |
| 185 | adap->dev.release = &i2c_adapter_dev_release; | 185 | adap->dev.release = &i2c_adapter_dev_release; |
| 186 | device_register(&adap->dev); | 186 | res = device_register(&adap->dev); |
| 187 | device_create_file(&adap->dev, &dev_attr_name); | 187 | if (res) |
| 188 | goto out_list; | ||
| 189 | res = device_create_file(&adap->dev, &dev_attr_name); | ||
| 190 | if (res) | ||
| 191 | goto out_unregister; | ||
| 188 | 192 | ||
| 189 | /* Add this adapter to the i2c_adapter class */ | 193 | /* Add this adapter to the i2c_adapter class */ |
| 190 | memset(&adap->class_dev, 0x00, sizeof(struct class_device)); | 194 | memset(&adap->class_dev, 0x00, sizeof(struct class_device)); |
| 191 | adap->class_dev.dev = &adap->dev; | 195 | adap->class_dev.dev = &adap->dev; |
| 192 | adap->class_dev.class = &i2c_adapter_class; | 196 | adap->class_dev.class = &i2c_adapter_class; |
| 193 | strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); | 197 | strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); |
| 194 | class_device_register(&adap->class_dev); | 198 | res = class_device_register(&adap->class_dev); |
| 199 | if (res) | ||
| 200 | goto out_remove_name; | ||
| 195 | 201 | ||
| 196 | dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); | 202 | dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); |
| 197 | 203 | ||
| @@ -206,6 +212,17 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
| 206 | out_unlock: | 212 | out_unlock: |
| 207 | mutex_unlock(&core_lists); | 213 | mutex_unlock(&core_lists); |
| 208 | return res; | 214 | return res; |
| 215 | |||
| 216 | out_remove_name: | ||
| 217 | device_remove_file(&adap->dev, &dev_attr_name); | ||
| 218 | out_unregister: | ||
| 219 | init_completion(&adap->dev_released); /* Needed? */ | ||
| 220 | device_unregister(&adap->dev); | ||
| 221 | wait_for_completion(&adap->dev_released); | ||
| 222 | out_list: | ||
| 223 | list_del(&adap->list); | ||
| 224 | idr_remove(&i2c_adapter_idr, adap->nr); | ||
| 225 | goto out_unlock; | ||
| 209 | } | 226 | } |
| 210 | 227 | ||
| 211 | 228 | ||
| @@ -394,14 +411,14 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) | |||
| 394 | int i2c_attach_client(struct i2c_client *client) | 411 | int i2c_attach_client(struct i2c_client *client) |
| 395 | { | 412 | { |
| 396 | struct i2c_adapter *adapter = client->adapter; | 413 | struct i2c_adapter *adapter = client->adapter; |
| 414 | int res = 0; | ||
| 397 | 415 | ||
| 398 | mutex_lock(&adapter->clist_lock); | 416 | mutex_lock(&adapter->clist_lock); |
| 399 | if (__i2c_check_addr(client->adapter, client->addr)) { | 417 | if (__i2c_check_addr(client->adapter, client->addr)) { |
| 400 | mutex_unlock(&adapter->clist_lock); | 418 | res = -EBUSY; |
| 401 | return -EBUSY; | 419 | goto out_unlock; |
| 402 | } | 420 | } |
| 403 | list_add_tail(&client->list,&adapter->clients); | 421 | list_add_tail(&client->list,&adapter->clients); |
| 404 | mutex_unlock(&adapter->clist_lock); | ||
| 405 | 422 | ||
| 406 | if (adapter->client_register) { | 423 | if (adapter->client_register) { |
| 407 | if (adapter->client_register(client)) { | 424 | if (adapter->client_register(client)) { |
| @@ -422,10 +439,26 @@ int i2c_attach_client(struct i2c_client *client) | |||
| 422 | "%d-%04x", i2c_adapter_id(adapter), client->addr); | 439 | "%d-%04x", i2c_adapter_id(adapter), client->addr); |
| 423 | dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", | 440 | dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", |
| 424 | client->name, client->dev.bus_id); | 441 | client->name, client->dev.bus_id); |
| 425 | device_register(&client->dev); | 442 | res = device_register(&client->dev); |
| 426 | device_create_file(&client->dev, &dev_attr_client_name); | 443 | if (res) |
| 427 | 444 | goto out_list; | |
| 428 | return 0; | 445 | res = device_create_file(&client->dev, &dev_attr_client_name); |
| 446 | if (res) | ||
| 447 | goto out_unregister; | ||
| 448 | |||
| 449 | out_unlock: | ||
| 450 | mutex_unlock(&adapter->clist_lock); | ||
| 451 | return res; | ||
| 452 | |||
| 453 | out_unregister: | ||
| 454 | init_completion(&client->released); /* Needed? */ | ||
| 455 | device_unregister(&client->dev); | ||
| 456 | wait_for_completion(&client->released); | ||
| 457 | out_list: | ||
| 458 | list_del(&client->list); | ||
| 459 | dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " | ||
| 460 | "(%d)\n", client->name, client->addr, res); | ||
| 461 | goto out_unlock; | ||
| 429 | } | 462 | } |
| 430 | 463 | ||
| 431 | 464 | ||
| @@ -674,11 +707,16 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind, | |||
| 674 | 707 | ||
| 675 | /* Finally call the custom detection function */ | 708 | /* Finally call the custom detection function */ |
| 676 | err = found_proc(adapter, addr, kind); | 709 | err = found_proc(adapter, addr, kind); |
| 677 | |||
| 678 | /* -ENODEV can be returned if there is a chip at the given address | 710 | /* -ENODEV can be returned if there is a chip at the given address |
| 679 | but it isn't supported by this chip driver. We catch it here as | 711 | but it isn't supported by this chip driver. We catch it here as |
| 680 | this isn't an error. */ | 712 | this isn't an error. */ |
| 681 | return (err == -ENODEV) ? 0 : err; | 713 | if (err == -ENODEV) |
| 714 | err = 0; | ||
| 715 | |||
| 716 | if (err) | ||
| 717 | dev_warn(&adapter->dev, "Client creation failed at 0x%x (%d)\n", | ||
| 718 | addr, err); | ||
| 719 | return err; | ||
| 682 | } | 720 | } |
| 683 | 721 | ||
| 684 | int i2c_probe(struct i2c_adapter *adapter, | 722 | int i2c_probe(struct i2c_adapter *adapter, |
| @@ -868,7 +906,7 @@ s32 i2c_smbus_read_byte(struct i2c_client *client) | |||
| 868 | I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) | 906 | I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) |
| 869 | return -1; | 907 | return -1; |
| 870 | else | 908 | else |
| 871 | return 0x0FF & data.byte; | 909 | return data.byte; |
| 872 | } | 910 | } |
| 873 | 911 | ||
| 874 | s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) | 912 | s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) |
| @@ -884,7 +922,7 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) | |||
| 884 | I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) | 922 | I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) |
| 885 | return -1; | 923 | return -1; |
| 886 | else | 924 | else |
| 887 | return 0x0FF & data.byte; | 925 | return data.byte; |
| 888 | } | 926 | } |
| 889 | 927 | ||
| 890 | s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) | 928 | s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) |
| @@ -903,7 +941,7 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) | |||
| 903 | I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) | 941 | I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) |
| 904 | return -1; | 942 | return -1; |
| 905 | else | 943 | else |
| 906 | return 0x0FFFF & data.word; | 944 | return data.word; |
| 907 | } | 945 | } |
| 908 | 946 | ||
| 909 | s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) | 947 | s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) |
| @@ -1006,7 +1044,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | |||
| 1006 | else { | 1044 | else { |
| 1007 | msg[0].len=3; | 1045 | msg[0].len=3; |
| 1008 | msgbuf0[1] = data->word & 0xff; | 1046 | msgbuf0[1] = data->word & 0xff; |
| 1009 | msgbuf0[2] = (data->word >> 8) & 0xff; | 1047 | msgbuf0[2] = data->word >> 8; |
| 1010 | } | 1048 | } |
| 1011 | break; | 1049 | break; |
| 1012 | case I2C_SMBUS_PROC_CALL: | 1050 | case I2C_SMBUS_PROC_CALL: |
| @@ -1015,7 +1053,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | |||
| 1015 | msg[0].len = 3; | 1053 | msg[0].len = 3; |
| 1016 | msg[1].len = 2; | 1054 | msg[1].len = 2; |
| 1017 | msgbuf0[1] = data->word & 0xff; | 1055 | msgbuf0[1] = data->word & 0xff; |
| 1018 | msgbuf0[2] = (data->word >> 8) & 0xff; | 1056 | msgbuf0[2] = data->word >> 8; |
| 1019 | break; | 1057 | break; |
| 1020 | case I2C_SMBUS_BLOCK_DATA: | 1058 | case I2C_SMBUS_BLOCK_DATA: |
| 1021 | if (read_write == I2C_SMBUS_READ) { | 1059 | if (read_write == I2C_SMBUS_READ) { |
