diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-03-12 22:56:15 +0100 |
---|---|---|
committer | Hans Verkuil <hverkuil@xs4all.nl> | 2009-03-12 22:56:15 +0100 |
commit | 0efc193045eedcc05a28b5502f6dfaed87b434e8 (patch) | |
tree | b4a7bb36687fb738c7c3a51ef1f77d08742d8567 | |
parent | e3752e7d1b2f53cf53597d07faac7d9f65d43ff1 (diff) | |
download | mediapointer-dvb-s2-0efc193045eedcc05a28b5502f6dfaed87b434e8.tar.gz mediapointer-dvb-s2-0efc193045eedcc05a28b5502f6dfaed87b434e8.tar.bz2 |
v4l2-common: add missing i2c_unregister_device.
From: Hans Verkuil <hverkuil@xs4all.nl>
If the i2c sub-device cannot be found, then we must unregister the i2c_client.
Otherwise this will prevent a possible probe for a different device on that same
address.
Priority: normal
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
-rw-r--r-- | linux/drivers/media/video/v4l2-common.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index a5ce43102..32d0246d5 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -856,11 +856,11 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, We need better support from the kernel so that we can easily wait for the load to finish. */ if (client == NULL || client->driver == NULL) - return NULL; + goto error; /* Lock the module so we can safely get the v4l2_subdev pointer */ if (!try_module_get(client->driver->driver.owner)) - return NULL; + goto error; sd = i2c_get_clientdata(client); /* Register with the v4l2_device which increases the module's @@ -869,8 +869,15 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - return sd; +error: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) + /* If we have a client but no subdev, then something went wrong and + we must unregister the client. */ + if (client && sd == NULL) + i2c_unregister_device(client); +#endif + return sd; } EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev); @@ -918,11 +925,11 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, We need better support from the kernel so that we can easily wait for the load to finish. */ if (client == NULL || client->driver == NULL) - return NULL; + goto error; /* Lock the module so we can safely get the v4l2_subdev pointer */ if (!try_module_get(client->driver->driver.owner)) - return NULL; + goto error; sd = i2c_get_clientdata(client); /* Register with the v4l2_device which increases the module's @@ -931,6 +938,14 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); + +error: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) + /* If we have a client but no subdev, then something went wrong and + we must unregister the client. */ + if (client && sd == NULL) + i2c_unregister_device(client); +#endif return sd; } EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev); |