From 1edc246c32dafd03979a341eec2528b7cdf5c37d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 15 Sep 2010 15:59:53 -0300 Subject: V4L/DVB: v4l: remove unused i2c-id.h headers Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/tef6862.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 90cae90277e7..7c0d77751f6e 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From cf9b475d5f9b58c23aca76b367f8318743d064e9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Sep 2010 09:56:22 -0300 Subject: V4L/DVB: radio-si470x: remove the BKL lock used internally at the driver Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-usb.c | 17 ++++++++--------- drivers/media/radio/si470x/radio-si470x.h | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 5ec13e50a9f0..392e84fe90ef 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -517,7 +517,7 @@ int si470x_fops_open(struct file *file) struct si470x_device *radio = video_drvdata(file); int retval; - lock_kernel(); + mutex_lock(&radio->lock); radio->users++; retval = usb_autopm_get_interface(radio->intf); @@ -558,7 +558,7 @@ int si470x_fops_open(struct file *file) } done: - unlock_kernel(); + mutex_unlock(&radio->lock); return retval; } @@ -577,7 +577,7 @@ int si470x_fops_release(struct file *file) goto done; } - mutex_lock(&radio->disconnect_lock); + mutex_lock(&radio->lock); radio->users--; if (radio->users == 0) { /* shutdown interrupt handler */ @@ -591,7 +591,7 @@ int si470x_fops_release(struct file *file) video_unregister_device(radio->videodev); kfree(radio->int_in_buffer); kfree(radio->buffer); - mutex_unlock(&radio->disconnect_lock); + mutex_unlock(&radio->lock); kfree(radio); goto done; } @@ -603,7 +603,7 @@ int si470x_fops_release(struct file *file) retval = si470x_stop(radio); usb_autopm_put_interface(radio->intf); } - mutex_unlock(&radio->disconnect_lock); + mutex_unlock(&radio->lock); done: return retval; } @@ -661,7 +661,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, radio->disconnected = 0; radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; - mutex_init(&radio->disconnect_lock); mutex_init(&radio->lock); iface_desc = intf->cur_altsetting; @@ -830,7 +829,7 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); - mutex_lock(&radio->disconnect_lock); + mutex_lock(&radio->lock); radio->disconnected = 1; usb_set_intfdata(intf, NULL); if (radio->users == 0) { @@ -843,10 +842,10 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) kfree(radio->int_in_buffer); video_unregister_device(radio->videodev); kfree(radio->buffer); - mutex_unlock(&radio->disconnect_lock); + mutex_unlock(&radio->lock); kfree(radio); } else { - mutex_unlock(&radio->disconnect_lock); + mutex_unlock(&radio->lock); } } diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 3cd0a29cd6e7..d3d86ba6e547 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -177,7 +177,6 @@ struct si470x_device { /* driver management */ unsigned char disconnected; - struct mutex disconnect_lock; #endif #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) -- cgit v1.2.3 From f2f8e8503e16985a784ed4e3fc5125fd5f86adf6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Sep 2010 08:35:45 -0300 Subject: V4L/DVB: radio-si470x: use unlocked ioctl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-common.c | 27 +++++++++++++++++++----- drivers/media/radio/si470x/radio-si470x.h | 1 - 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9927a595b426..61be9887e6a1 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -408,17 +408,15 @@ done: /* * si470x_rds_on - switch on rds reception */ -int si470x_rds_on(struct si470x_device *radio) +static int si470x_rds_on(struct si470x_device *radio) { int retval; /* sysconfig 1 */ - mutex_lock(&radio->lock); radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; retval = si470x_set_register(radio, SYSCONFIG1); if (retval < 0) radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; - mutex_unlock(&radio->lock); return retval; } @@ -440,6 +438,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, unsigned int block_count = 0; /* switch on rds reception */ + mutex_lock(&radio->lock); if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) si470x_rds_on(radio); @@ -480,9 +479,9 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, buf += 3; retval += 3; } - mutex_unlock(&radio->lock); done: + mutex_unlock(&radio->lock); return retval; } @@ -497,8 +496,11 @@ static unsigned int si470x_fops_poll(struct file *file, int retval = 0; /* switch on rds reception */ + + mutex_lock(&radio->lock); if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) si470x_rds_on(radio); + mutex_unlock(&radio->lock); poll_wait(file, &radio->read_queue, pts); @@ -516,7 +518,7 @@ static const struct v4l2_file_operations si470x_fops = { .owner = THIS_MODULE, .read = si470x_fops_read, .poll = si470x_fops_poll, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, .open = si470x_fops_open, .release = si470x_fops_release, }; @@ -572,6 +574,7 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -594,6 +597,8 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "get control failed with %d\n", retval); + + mutex_unlock(&radio->lock); return retval; } @@ -607,6 +612,7 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -633,6 +639,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "set control failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } @@ -662,6 +669,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -737,6 +745,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "get tuner failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } @@ -750,6 +759,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -776,6 +786,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "set tuner failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } @@ -790,6 +801,7 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, int retval = 0; /* safety checks */ + mutex_lock(&radio->lock); retval = si470x_disconnect_check(radio); if (retval) goto done; @@ -806,6 +818,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "get frequency failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } @@ -819,6 +832,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -835,6 +849,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "set frequency failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } @@ -848,6 +863,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, struct si470x_device *radio = video_drvdata(file); int retval = 0; + mutex_lock(&radio->lock); /* safety checks */ retval = si470x_disconnect_check(radio); if (retval) @@ -864,6 +880,7 @@ done: if (retval < 0) dev_warn(&radio->videodev->dev, "set hardware frequency seek failed with %d\n", retval); + mutex_unlock(&radio->lock); return retval; } diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index d3d86ba6e547..ea12782359a0 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -220,7 +220,6 @@ int si470x_disconnect_check(struct si470x_device *radio); int si470x_set_freq(struct si470x_device *radio, unsigned int freq); int si470x_start(struct si470x_device *radio); int si470x_stop(struct si470x_device *radio); -int si470x_rds_on(struct si470x_device *radio); int si470x_fops_open(struct file *file); int si470x_fops_release(struct file *file); int si470x_vidioc_querycap(struct file *file, void *priv, -- cgit v1.2.3 From 361ae54fc7f06a0cee1fb6e6a659a42556b56702 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 26 Sep 2010 08:01:18 -0300 Subject: V4L/DVB: radio-mr800: remove BKL Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 74 ++++++--------------------------------- 1 file changed, 10 insertions(+), 64 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 353b82855949..97967ad3cd12 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -176,8 +176,6 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) int retval; int size; - BUG_ON(!mutex_is_locked(&radio->lock)); - radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; @@ -207,8 +205,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) int size; unsigned short freq_send = 0x10 + (freq >> 3) / 25; - BUG_ON(!mutex_is_locked(&radio->lock)); - radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; @@ -253,8 +249,6 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) int retval; int size; - BUG_ON(!mutex_is_locked(&radio->lock)); - radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; @@ -290,11 +284,9 @@ static void usb_amradio_disconnect(struct usb_interface *intf) struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); mutex_lock(&radio->lock); - radio->usbdev = NULL; - mutex_unlock(&radio->lock); - v4l2_device_disconnect(&radio->v4l2_dev); video_unregister_device(&radio->videodev); + mutex_unlock(&radio->lock); } /* vidioc_querycap - query device capabilities */ @@ -503,28 +495,18 @@ out: static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_drvdata(file); - int retval = 0; - - mutex_lock(&radio->lock); - - if (!radio->usbdev) { - retval = -EIO; - goto unlock; - } + int retval; file->private_data = radio; retval = usb_autopm_get_interface(radio->intf); if (retval) - goto unlock; + return retval; if (unlikely(!radio->initialized)) { retval = usb_amradio_init(radio); if (retval) usb_autopm_put_interface(radio->intf); } - -unlock: - mutex_unlock(&radio->lock); return retval; } @@ -532,37 +514,9 @@ unlock: static int usb_amradio_close(struct file *file) { struct amradio_device *radio = file->private_data; - int retval = 0; - - mutex_lock(&radio->lock); - - if (!radio->usbdev) - retval = -EIO; - else - usb_autopm_put_interface(radio->intf); - - mutex_unlock(&radio->lock); - return retval; -} - -static long usb_amradio_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct amradio_device *radio = file->private_data; - long retval = 0; - - mutex_lock(&radio->lock); - - if (!radio->usbdev) { - retval = -EIO; - goto unlock; - } - - retval = video_ioctl2(file, cmd, arg); -unlock: - mutex_unlock(&radio->lock); - return retval; + usb_autopm_put_interface(radio->intf); + return 0; } /* Suspend device - stop device. Need to be checked and fixed */ @@ -570,16 +524,12 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); - mutex_lock(&radio->lock); - if (!radio->muted && radio->initialized) { amradio_set_mute(radio, AMRADIO_STOP); radio->muted = 0; } dev_info(&intf->dev, "going into suspend..\n"); - - mutex_unlock(&radio->lock); return 0; } @@ -588,10 +538,8 @@ static int usb_amradio_resume(struct usb_interface *intf) { struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); - mutex_lock(&radio->lock); - if (unlikely(!radio->initialized)) - goto unlock; + return 0; if (radio->stereo) amradio_set_stereo(radio, WANT_STEREO); @@ -603,10 +551,7 @@ static int usb_amradio_resume(struct usb_interface *intf) if (!radio->muted) amradio_set_mute(radio, AMRADIO_START); -unlock: dev_info(&intf->dev, "coming out of suspend..\n"); - - mutex_unlock(&radio->lock); return 0; } @@ -615,7 +560,7 @@ static const struct v4l2_file_operations usb_amradio_fops = { .owner = THIS_MODULE, .open = usb_amradio_open, .release = usb_amradio_close, - .ioctl = usb_amradio_ioctl, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { @@ -671,19 +616,20 @@ static int usb_amradio_probe(struct usb_interface *intf, goto err_v4l2; } + mutex_init(&radio->lock); + strlcpy(radio->videodev.name, radio->v4l2_dev.name, sizeof(radio->videodev.name)); radio->videodev.v4l2_dev = &radio->v4l2_dev; radio->videodev.fops = &usb_amradio_fops; radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; radio->videodev.release = usb_amradio_video_device_release; + radio->videodev.lock = &radio->lock; radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; radio->curfreq = 95.16 * FREQ_MUL; - mutex_init(&radio->lock); - video_set_drvdata(&radio->videodev, radio); retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, -- cgit v1.2.3 From 85c55efb0a20c5dac435a6817ffb20fe988b9122 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 21 Sep 2010 05:49:42 -0300 Subject: V4L/DVB: radio-si4713: Release i2c adapter in driver cleanup paths Call to i2c_put_adapter was missing in radio_si4713_pdriver_probe and radio_si4713_pdriver_remove. Signed-off-by: Jarkko Nikula Acked-by: Eduardo Valentin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si4713.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 13554ab13f76..0a9fc4d2165c 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -296,14 +296,14 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) if (!sd) { dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); rval = -ENODEV; - goto unregister_v4l2_dev; + goto put_adapter; } rsdev->radio_dev = video_device_alloc(); if (!rsdev->radio_dev) { dev_err(&pdev->dev, "Failed to alloc video device.\n"); rval = -ENOMEM; - goto unregister_v4l2_dev; + goto put_adapter; } memcpy(rsdev->radio_dev, &radio_si4713_vdev_template, @@ -320,6 +320,8 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) free_vdev: video_device_release(rsdev->radio_dev); +put_adapter: + i2c_put_adapter(adapter); unregister_v4l2_dev: v4l2_device_unregister(&rsdev->v4l2_dev); free_rsdev: @@ -335,8 +337,12 @@ static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev) struct radio_si4713_device *rsdev = container_of(v4l2_dev, struct radio_si4713_device, v4l2_dev); + struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next, + struct v4l2_subdev, list); + struct i2c_client *client = v4l2_get_subdevdata(sd); video_unregister_device(rsdev->radio_dev); + i2c_put_adapter(client->adapter); v4l2_device_unregister(&rsdev->v4l2_dev); kfree(rsdev); -- cgit v1.2.3 From 9c84d89bf13b702ca0e0db5eb3880300c4bd58f4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 11 Oct 2010 12:36:37 -0300 Subject: [media] radio-mr800: fix locking order Don't hold the lock before unregistering the device, since when the device is unregistered the datastruct containing the lock may be freed (if the refcount went to 0). Also fixed the framework documentation that erroneously suggested the wrong locking order as well. Reported-by: David Ellingsworth Signed-off-by: Hans Verkuil Acked-by: David Ellingsworth Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/v4l2-framework.txt | 2 +- drivers/media/radio/radio-mr800.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/radio') diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index a128e012a45c..f22f35c271f3 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -488,7 +488,7 @@ also waits in the code, then you should do the same to allow other processes to access the device node while the first process is waiting for something. The implementation of a hotplug disconnect should also take the lock before -calling v4l2_device_disconnect and video_unregister_device. +calling v4l2_device_disconnect. video_device registration ------------------------- diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 97967ad3cd12..2f56b26cece9 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -285,8 +285,8 @@ static void usb_amradio_disconnect(struct usb_interface *intf) mutex_lock(&radio->lock); v4l2_device_disconnect(&radio->v4l2_dev); - video_unregister_device(&radio->videodev); mutex_unlock(&radio->lock); + video_unregister_device(&radio->videodev); } /* vidioc_querycap - query device capabilities */ -- cgit v1.2.3 From cb9bc962a10144d3a70651f1f5c755b34d8d5bf4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 24 Sep 2010 08:45:07 -0300 Subject: [media] radio-si4713: Don't use module names to load I2C modules With the v4l2_i2c_new_subdev* functions now supporting loading modules based on modaliases, replace the hardcoded module name passed to those functions by NULL. As no board seems to use this driver, no platform data has been checked. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si4713.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 0a9fc4d2165c..6a435786b63d 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -291,7 +291,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) goto unregister_v4l2_dev; } - sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, "si4713_i2c", + sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL, pdata->subdev_board_info, NULL); if (!sd) { dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); -- cgit v1.2.3 From a682d4cb768381039bdafdc3c04c53cf8d70dcf0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 17 Oct 2010 09:26:18 -0300 Subject: [media] [RFC] radio-mr800: locking fixes - serialize the suspend and resume functions using the global lock. - do not call usb_autopm_put_interface after a disconnect. - fix a race when disconnecting the device. Reported-by: David Ellingsworth Signed-off-by: Hans Verkuil Acked-by: David Ellingsworth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 2f56b26cece9..b540e8072e92 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -284,9 +284,13 @@ static void usb_amradio_disconnect(struct usb_interface *intf) struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); mutex_lock(&radio->lock); + /* increase the device node's refcount */ + get_device(&radio->videodev.dev); v4l2_device_disconnect(&radio->v4l2_dev); - mutex_unlock(&radio->lock); video_unregister_device(&radio->videodev); + mutex_unlock(&radio->lock); + /* decrease the device node's refcount, allowing it to be released */ + put_device(&radio->videodev.dev); } /* vidioc_querycap - query device capabilities */ @@ -515,7 +519,8 @@ static int usb_amradio_close(struct file *file) { struct amradio_device *radio = file->private_data; - usb_autopm_put_interface(radio->intf); + if (video_is_registered(&radio->videodev)) + usb_autopm_put_interface(radio->intf); return 0; } @@ -524,10 +529,12 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); + mutex_lock(&radio->lock); if (!radio->muted && radio->initialized) { amradio_set_mute(radio, AMRADIO_STOP); radio->muted = 0; } + mutex_unlock(&radio->lock); dev_info(&intf->dev, "going into suspend..\n"); return 0; @@ -538,8 +545,9 @@ static int usb_amradio_resume(struct usb_interface *intf) { struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); + mutex_lock(&radio->lock); if (unlikely(!radio->initialized)) - return 0; + goto unlock; if (radio->stereo) amradio_set_stereo(radio, WANT_STEREO); @@ -551,6 +559,9 @@ static int usb_amradio_resume(struct usb_interface *intf) if (!radio->muted) amradio_set_mute(radio, AMRADIO_START); +unlock: + mutex_unlock(&radio->lock); + dev_info(&intf->dev, "coming out of suspend..\n"); return 0; } -- cgit v1.2.3 From cb0ed22270129b980257fa9c83b152f09ecd9eda Mon Sep 17 00:00:00 2001 From: Matti Aaltonen Date: Mon, 18 Oct 2010 06:54:14 -0300 Subject: [media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-cadet.c | 3 ++- drivers/media/radio/si470x/radio-si470x-common.c | 2 +- drivers/media/radio/si4713-i2c.c | 2 +- drivers/media/video/saa6588.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media/radio') diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 482d0f3be5ff..b701ea6e7c73 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -374,7 +374,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, switch (v->index) { case 0: strlcpy(v->name, "FM", sizeof(v->name)); - v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS; + v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | + V4L2_TUNER_CAP_RDS_BLOCK_IO; v->rangelow = 1400; /* 87.5 MHz */ v->rangehigh = 1728; /* 108.0 MHz */ v->rxsubchans = cadet_getstereo(dev); diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 61be9887e6a1..ac76dfe5b3fa 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -689,7 +689,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, tuner->type = V4L2_TUNER_RADIO; #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS; + V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; #else tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; #endif diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index fc7f4b794649..a6e6f1987a3a 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c @@ -1804,7 +1804,7 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm) strncpy(vm->name, "FM Modulator", 32); vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | - V4L2_TUNER_CAP_RDS; + V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS; /* Report current frequency range limits */ vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW); diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 2ddd68cc3f93..984c0feb2a4e 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c @@ -429,7 +429,7 @@ static int saa6588_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) { struct saa6588 *s = to_saa6588(sd); - vt->capability |= V4L2_TUNER_CAP_RDS; + vt->capability |= V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; if (s->sync) vt->rxsubchans |= V4L2_TUNER_SUB_RDS; return 0; -- cgit v1.2.3