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)
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 = {
.name = "i2c_adapter",
.bus = &i2c_bus_type,
......@@ -62,10 +68,23 @@ static struct device_driver i2c_adapter_driver = {
.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 = {
.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
......@@ -99,6 +118,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
adap->dev.parent = &legacy_bus;
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);
/* Add this adapter to the i2c_adapter class */
......@@ -161,10 +181,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
}
/* clean up the sysfs representation */
init_completion(&adap->dev_released);
init_completion(&adap->class_dev_released);
class_device_unregister(&adap->class_dev);
device_unregister(&adap->dev);
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"));
out_unlock:
......@@ -329,6 +355,7 @@ int i2c_attach_client(struct i2c_client *client)
client->dev.parent = &client->adapter->dev;
client->dev.driver = &client->driver->driver;
client->dev.bus = &i2c_bus_type;
client->dev.release = &i2c_client_release;
snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
"%d-%04x", i2c_adapter_id(adapter), client->addr);
......@@ -359,8 +386,10 @@ int i2c_detach_client(struct i2c_client *client)
down(&adapter->clist_lock);
list_del(&client->list);
init_completion(&client->released);
device_unregister(&client->dev);
up(&adapter->clist_lock);
wait_for_completion(&client->released);
out:
return res;
......
......@@ -167,6 +167,7 @@ struct i2c_client {
struct device dev; /* the device structure */
struct list_head list;
char name[DEVICE_NAME_SIZE];
struct completion released;
};
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
......@@ -253,8 +254,11 @@ struct i2c_adapter {
struct list_head clients;
struct list_head list;
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)
{
......
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