X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fi2c%2Fi2c-core.c;h=7ca81f42d14bfd7c1ab5834b2a6cb853587259a9;hb=7d314e346d6081e8013a96206e601a48528d8f60;hp=a45155f799d4405dae2d67ca06d7168f64fe9d3d;hpb=c71bd6944eb1458b7887af1783101f5a46140c40;p=linux-2.6-omap-h63xx.git diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a45155f799d..7ca81f42d14 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) sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); adap->dev.driver = &i2c_adapter_driver; adap->dev.release = &i2c_adapter_dev_release; - device_register(&adap->dev); - device_create_file(&adap->dev, &dev_attr_name); + res = device_register(&adap->dev); + if (res) + goto out_list; + res = device_create_file(&adap->dev, &dev_attr_name); + if (res) + goto out_unregister; /* Add this adapter to the i2c_adapter class */ memset(&adap->class_dev, 0x00, sizeof(struct class_device)); adap->class_dev.dev = &adap->dev; adap->class_dev.class = &i2c_adapter_class; strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); - class_device_register(&adap->class_dev); + res = class_device_register(&adap->class_dev); + if (res) + goto out_remove_name; dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); @@ -206,6 +212,17 @@ int i2c_add_adapter(struct i2c_adapter *adap) out_unlock: mutex_unlock(&core_lists); return res; + +out_remove_name: + device_remove_file(&adap->dev, &dev_attr_name); +out_unregister: + init_completion(&adap->dev_released); /* Needed? */ + device_unregister(&adap->dev); + wait_for_completion(&adap->dev_released); +out_list: + list_del(&adap->list); + idr_remove(&i2c_adapter_idr, adap->nr); + goto out_unlock; } @@ -394,23 +411,15 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) int i2c_attach_client(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; + int res = 0; mutex_lock(&adapter->clist_lock); if (__i2c_check_addr(client->adapter, client->addr)) { - mutex_unlock(&adapter->clist_lock); - return -EBUSY; + res = -EBUSY; + goto out_unlock; } list_add_tail(&client->list,&adapter->clients); - mutex_unlock(&adapter->clist_lock); - if (adapter->client_register) { - if (adapter->client_register(client)) { - dev_dbg(&adapter->dev, "client_register " - "failed for client [%s] at 0x%02x\n", - client->name, client->addr); - } - } - client->usage_count = 0; client->dev.parent = &client->adapter->dev; @@ -422,10 +431,35 @@ int i2c_attach_client(struct i2c_client *client) "%d-%04x", i2c_adapter_id(adapter), client->addr); dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", client->name, client->dev.bus_id); - device_register(&client->dev); - device_create_file(&client->dev, &dev_attr_client_name); - + res = device_register(&client->dev); + if (res) + goto out_list; + res = device_create_file(&client->dev, &dev_attr_client_name); + if (res) + goto out_unregister; + mutex_unlock(&adapter->clist_lock); + + if (adapter->client_register) { + if (adapter->client_register(client)) { + dev_dbg(&adapter->dev, "client_register " + "failed for client [%s] at 0x%02x\n", + client->name, client->addr); + } + } + return 0; + +out_unregister: + init_completion(&client->released); /* Needed? */ + device_unregister(&client->dev); + wait_for_completion(&client->released); +out_list: + list_del(&client->list); + dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " + "(%d)\n", client->name, client->addr, res); +out_unlock: + mutex_unlock(&adapter->clist_lock); + return res; } @@ -674,11 +708,16 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind, /* Finally call the custom detection function */ err = found_proc(adapter, addr, kind); - /* -ENODEV can be returned if there is a chip at the given address but it isn't supported by this chip driver. We catch it here as this isn't an error. */ - return (err == -ENODEV) ? 0 : err; + if (err == -ENODEV) + err = 0; + + if (err) + dev_warn(&adapter->dev, "Client creation failed at 0x%x (%d)\n", + addr, err); + return err; } int i2c_probe(struct i2c_adapter *adapter, @@ -756,9 +795,9 @@ int i2c_probe(struct i2c_adapter *adapter, "parameter for adapter %d, " "addr 0x%02x\n", adap_id, address_data->ignore[j + 1]); + ignore = 1; + break; } - ignore = 1; - break; } if (ignore) continue; @@ -868,7 +907,7 @@ s32 i2c_smbus_read_byte(struct i2c_client *client) I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) return -1; else - return 0x0FF & data.byte; + return data.byte; } s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) @@ -884,7 +923,7 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) return -1; else - return 0x0FF & data.byte; + return data.byte; } s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) @@ -903,7 +942,7 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) return -1; else - return 0x0FFFF & data.word; + return data.word; } s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) @@ -1006,7 +1045,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, else { msg[0].len=3; msgbuf0[1] = data->word & 0xff; - msgbuf0[2] = (data->word >> 8) & 0xff; + msgbuf0[2] = data->word >> 8; } break; case I2C_SMBUS_PROC_CALL: @@ -1015,7 +1054,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, msg[0].len = 3; msg[1].len = 2; msgbuf0[1] = data->word & 0xff; - msgbuf0[2] = (data->word >> 8) & 0xff; + msgbuf0[2] = data->word >> 8; break; case I2C_SMBUS_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) {