diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-isa.c | 29 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 53 |
2 files changed, 69 insertions, 13 deletions
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index c3e1d3e888d7..d7486e586068 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
@@ -125,6 +125,8 @@ int i2c_isa_del_driver(struct i2c_driver *driver) | |||
125 | 125 | ||
126 | static int __init i2c_isa_init(void) | 126 | static int __init i2c_isa_init(void) |
127 | { | 127 | { |
128 | int err; | ||
129 | |||
128 | mutex_init(&isa_adapter.clist_lock); | 130 | mutex_init(&isa_adapter.clist_lock); |
129 | INIT_LIST_HEAD(&isa_adapter.clients); | 131 | INIT_LIST_HEAD(&isa_adapter.clients); |
130 | 132 | ||
@@ -133,8 +135,16 @@ static int __init i2c_isa_init(void) | |||
133 | sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); | 135 | sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); |
134 | isa_adapter.dev.driver = &i2c_adapter_driver; | 136 | isa_adapter.dev.driver = &i2c_adapter_driver; |
135 | isa_adapter.dev.release = &i2c_adapter_dev_release; | 137 | isa_adapter.dev.release = &i2c_adapter_dev_release; |
136 | device_register(&isa_adapter.dev); | 138 | err = device_register(&isa_adapter.dev); |
137 | device_create_file(&isa_adapter.dev, &dev_attr_name); | 139 | if (err) { |
140 | printk(KERN_ERR "i2c-isa: Failed to register device\n"); | ||
141 | goto exit; | ||
142 | } | ||
143 | err = device_create_file(&isa_adapter.dev, &dev_attr_name); | ||
144 | if (err) { | ||
145 | printk(KERN_ERR "i2c-isa: Failed to create name file\n"); | ||
146 | goto exit_unregister; | ||
147 | } | ||
138 | 148 | ||
139 | /* Add this adapter to the i2c_adapter class */ | 149 | /* Add this adapter to the i2c_adapter class */ |
140 | memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device)); | 150 | memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device)); |
@@ -142,11 +152,24 @@ static int __init i2c_isa_init(void) | |||
142 | isa_adapter.class_dev.class = &i2c_adapter_class; | 152 | isa_adapter.class_dev.class = &i2c_adapter_class; |
143 | strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id, | 153 | strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id, |
144 | BUS_ID_SIZE); | 154 | BUS_ID_SIZE); |
145 | class_device_register(&isa_adapter.class_dev); | 155 | err = class_device_register(&isa_adapter.class_dev); |
156 | if (err) { | ||
157 | printk(KERN_ERR "i2c-isa: Failed to register class device\n"); | ||
158 | goto exit_remove_name; | ||
159 | } | ||
146 | 160 | ||
147 | dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); | 161 | dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); |
148 | 162 | ||
149 | return 0; | 163 | return 0; |
164 | |||
165 | exit_remove_name: | ||
166 | device_remove_file(&isa_adapter.dev, &dev_attr_name); | ||
167 | exit_unregister: | ||
168 | init_completion(&isa_adapter.dev_released); /* Needed? */ | ||
169 | device_unregister(&isa_adapter.dev); | ||
170 | wait_for_completion(&isa_adapter.dev_released); | ||
171 | exit: | ||
172 | return err; | ||
150 | } | 173 | } |
151 | 174 | ||
152 | static void __exit i2c_isa_exit(void) | 175 | static void __exit i2c_isa_exit(void) |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 9cb277d6aa48..36e1214b0b1d 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 | ||