Commit 46df16bf authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

I2C: fix up driver model programming error.

There was no release function for the objects.
bad greg, no biscuit...
parent 521a2590
...@@ -55,6 +55,12 @@ int i2c_device_remove(struct device *dev) ...@@ -55,6 +55,12 @@ int i2c_device_remove(struct device *dev)
return 0; return 0;
} }
static void i2c_adapter_dev_release(struct device *dev)
{
struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
complete(&adap->dev_released);
}
static struct device_driver i2c_adapter_driver = { static struct device_driver i2c_adapter_driver = {
.name = "i2c_adapter", .name = "i2c_adapter",
.bus = &i2c_bus_type, .bus = &i2c_bus_type,
...@@ -62,10 +68,23 @@ static struct device_driver i2c_adapter_driver = { ...@@ -62,10 +68,23 @@ static struct device_driver i2c_adapter_driver = {
.remove = i2c_device_remove, .remove = i2c_device_remove,
}; };
static void i2c_adapter_class_dev_release(struct class_device *dev)
{
struct i2c_adapter *adap = class_dev_to_i2c_adapter(dev);
complete(&adap->class_dev_released);
}
static struct class i2c_adapter_class = { static struct class i2c_adapter_class = {
.name = "i2c-adapter" .name = "i2c-adapter",
.release = &i2c_adapter_class_dev_release,
}; };
static void i2c_client_release(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
complete(&client->released);
}
/* --------------------------------------------------- /* ---------------------------------------------------
* registering functions * registering functions
...@@ -99,6 +118,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) ...@@ -99,6 +118,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
adap->dev.parent = &legacy_bus; adap->dev.parent = &legacy_bus;
sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
adap->dev.driver = &i2c_adapter_driver; adap->dev.driver = &i2c_adapter_driver;
adap->dev.release = &i2c_adapter_dev_release;
device_register(&adap->dev); device_register(&adap->dev);
/* Add this adapter to the i2c_adapter class */ /* Add this adapter to the i2c_adapter class */
...@@ -161,10 +181,16 @@ int i2c_del_adapter(struct i2c_adapter *adap) ...@@ -161,10 +181,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
} }
/* clean up the sysfs representation */ /* clean up the sysfs representation */
init_completion(&adap->dev_released);
init_completion(&adap->class_dev_released);
class_device_unregister(&adap->class_dev); class_device_unregister(&adap->class_dev);
device_unregister(&adap->dev); device_unregister(&adap->dev);
list_del(&adap->list); list_del(&adap->list);
/* wait for sysfs to drop all references */
wait_for_completion(&adap->dev_released);
wait_for_completion(&adap->class_dev_released);
DEB(dev_dbg(&adap->dev, "adapter unregistered\n")); DEB(dev_dbg(&adap->dev, "adapter unregistered\n"));
out_unlock: out_unlock:
...@@ -329,6 +355,7 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -329,6 +355,7 @@ int i2c_attach_client(struct i2c_client *client)
client->dev.parent = &client->adapter->dev; client->dev.parent = &client->adapter->dev;
client->dev.driver = &client->driver->driver; client->dev.driver = &client->driver->driver;
client->dev.bus = &i2c_bus_type; client->dev.bus = &i2c_bus_type;
client->dev.release = &i2c_client_release;
snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
"%d-%04x", i2c_adapter_id(adapter), client->addr); "%d-%04x", i2c_adapter_id(adapter), client->addr);
...@@ -359,8 +386,10 @@ int i2c_detach_client(struct i2c_client *client) ...@@ -359,8 +386,10 @@ int i2c_detach_client(struct i2c_client *client)
down(&adapter->clist_lock); down(&adapter->clist_lock);
list_del(&client->list); list_del(&client->list);
init_completion(&client->released);
device_unregister(&client->dev); device_unregister(&client->dev);
up(&adapter->clist_lock); up(&adapter->clist_lock);
wait_for_completion(&client->released);
out: out:
return res; return res;
......
...@@ -167,6 +167,7 @@ struct i2c_client { ...@@ -167,6 +167,7 @@ struct i2c_client {
struct device dev; /* the device structure */ struct device dev; /* the device structure */
struct list_head list; struct list_head list;
char name[DEVICE_NAME_SIZE]; char name[DEVICE_NAME_SIZE];
struct completion released;
}; };
#define to_i2c_client(d) container_of(d, struct i2c_client, dev) #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
...@@ -253,8 +254,11 @@ struct i2c_adapter { ...@@ -253,8 +254,11 @@ struct i2c_adapter {
struct list_head clients; struct list_head clients;
struct list_head list; struct list_head list;
char name[DEVICE_NAME_SIZE]; char name[DEVICE_NAME_SIZE];
struct completion dev_released;
struct completion class_dev_released;
}; };
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) #define dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
#define class_dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, class_dev)
static inline void *i2c_get_adapdata (struct i2c_adapter *dev) static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment