From: Hans Verkuil Date: Fri, 17 Sep 2010 18:07:28 +0000 (-0300) Subject: V4L/DVB: usbvision: remove BKL from usbvision X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=8403472f19fea7e7cec7899e998f38b899e59604;p=openwrt%2Fstaging%2Fblogic.git V4L/DVB: usbvision: remove BKL from usbvision Removed the BKL from usbvision. There was an initialization bug as well where the i2c bus was registered twice. Although when the BKL was present no oops was generated, I did run into other i2c problems. Now that I protect against duplicate i2c registration that bug is now gone as well. But trying to disconnect the USB cable while someone is still using the device still leads to a crash. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 42ba28785750..a5fd2aa3646e 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -211,6 +211,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ I2C_CLIENT_END }; + if (usbvision->registered_i2c) + return 0; + memcpy(&usbvision->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); @@ -268,6 +271,8 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) &usbvision->i2c_adap, "tuner", "tuner", 0, v4l2_i2c_tuner_addrs(type)); + if (sd == NULL) + return -ENODEV; if (usbvision->tuner_type != -1) { tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; tun_setup.type = usbvision->tuner_type; @@ -275,14 +280,18 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) call_all(usbvision, tuner, s_type_addr, &tun_setup); } } + usbvision->registered_i2c = 1; return 0; } int usbvision_i2c_unregister(struct usb_usbvision *usbvision) { + if (!usbvision->registered_i2c) + return 0; i2c_del_adapter(&(usbvision->i2c_adap)); + usbvision->registered_i2c = 0; PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name); diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index c2690df33438..db6b828594f5 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -357,7 +357,7 @@ static int usbvision_v4l2_open(struct file *file) PDEBUG(DBG_IO, "open"); - lock_kernel(); + mutex_lock(&usbvision->lock); usbvision_reset_powerOffTimer(usbvision); if (usbvision->user) @@ -379,7 +379,6 @@ static int usbvision_v4l2_open(struct file *file) /* If so far no errors then we shall start the camera */ if (!errCode) { - mutex_lock(&usbvision->lock); if (usbvision->power == 0) { usbvision_power_on(usbvision); usbvision_i2c_register(usbvision); @@ -408,14 +407,13 @@ static int usbvision_v4l2_open(struct file *file) usbvision->initialized = 0; } } - mutex_unlock(&usbvision->lock); } /* prepare queues */ usbvision_empty_framequeues(usbvision); PDEBUG(DBG_IO, "success"); - unlock_kernel(); + mutex_unlock(&usbvision->lock); return errCode; } @@ -1645,8 +1643,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf, usbvision->usb_bandwidth = 0; usbvision->user = 0; usbvision->streaming = Stream_Off; - usbvision_register_video(usbvision); usbvision_configure_video(usbvision); + usbvision_register_video(usbvision); mutex_unlock(&usbvision->lock); usbvision_create_sysfs(usbvision->vdev); diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index d1b3cc0cd87f..cc4e96c8cd6c 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h @@ -363,6 +363,7 @@ struct usb_usbvision { /* i2c Declaration Section*/ struct i2c_adapter i2c_adap; + int registered_i2c; struct urb *ctrlUrb; unsigned char ctrlUrbBuffer[8];