summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c29
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c3
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c5
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h1
-rw-r--r--drivers/media/video/ir-kbd-i2c.c8
5 files changed, 24 insertions, 22 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 2a28882ee1d..bd82f017ccd 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -843,15 +843,25 @@ void cx231xx_release_resources(struct cx231xx *dev)
cx231xx_remove_from_devlist(dev);
+ cx231xx_ir_exit(dev);
+
/* Release I2C buses */
cx231xx_dev_uninit(dev);
- cx231xx_ir_exit(dev);
+ /* delete v4l2 device */
+ v4l2_device_unregister(&dev->v4l2_dev);
usb_put_dev(dev->udev);
/* Mark device as unused */
cx231xx_devused &= ~(1 << dev->devno);
+
+ kfree(dev->video_mode.alt_max_pkt_size);
+ kfree(dev->vbi_mode.alt_max_pkt_size);
+ kfree(dev->sliced_cc_mode.alt_max_pkt_size);
+ kfree(dev->ts1_mode.alt_max_pkt_size);
+ kfree(dev);
+ dev = NULL;
}
/*
@@ -1329,9 +1339,6 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
flush_request_modules(dev);
- /* delete v4l2 device */
- v4l2_device_unregister(&dev->v4l2_dev);
-
/* wait until all current v4l2 io is finished then deallocate
resources */
mutex_lock(&dev->lock);
@@ -1344,6 +1351,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
"deallocation are deferred on close.\n",
video_device_node_name(dev->vdev));
+ /* Even having users, it is safe to remove the RC i2c driver */
+ cx231xx_ir_exit(dev);
+
dev->state |= DEV_MISCONFIGURED;
if (dev->USE_ISO)
cx231xx_uninit_isoc(dev);
@@ -1354,21 +1364,14 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
wake_up_interruptible(&dev->wait_stream);
} else {
dev->state |= DEV_DISCONNECTED;
- cx231xx_release_resources(dev);
}
cx231xx_close_extension(dev);
mutex_unlock(&dev->lock);
- if (!dev->users) {
- kfree(dev->video_mode.alt_max_pkt_size);
- kfree(dev->vbi_mode.alt_max_pkt_size);
- kfree(dev->sliced_cc_mode.alt_max_pkt_size);
- kfree(dev->ts1_mode.alt_max_pkt_size);
- kfree(dev);
- dev = NULL;
- }
+ if (!dev->users)
+ cx231xx_release_resources(dev);
}
static struct usb_driver cx231xx_usb_driver = {
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index d4457f9488e..39e9878cb38 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -166,6 +166,9 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
u8 _i2c_nostop = 0;
u8 _i2c_reserve = 0;
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+
/* Get the I2C period, nostop and reserve parameters */
_i2c_period = i2c_bus->i2c_period;
_i2c_nostop = i2c_bus->i2c_nostop;
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 8a75a908e70..96176e9db5a 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -106,11 +106,14 @@ int cx231xx_ir_init(struct cx231xx *dev)
ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
ir_i2c_bus, info.addr);
- i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info);
+ dev->ir_i2c_client = i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info);
return 0;
}
void cx231xx_ir_exit(struct cx231xx *dev)
{
+ if (dev->ir_i2c_client)
+ i2c_unregister_device(dev->ir_i2c_client);
+ dev->ir_i2c_client = NULL;
}
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 2000bc64c49..5d498a4112d 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -621,6 +621,7 @@ struct cx231xx {
/* For I2C IR support */
struct IR_i2c_init_data init_data;
+ struct i2c_client *ir_i2c_client;
unsigned int stream_on:1; /* Locks streams */
unsigned int vbi_stream_on:1; /* Locks streams for VBI */
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 37d0c201251..a7c41d32f41 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -498,11 +498,3 @@ static void __exit ir_fini(void)
module_init(ir_init);
module_exit(ir_fini);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */