From patchwork Sun Oct 17 12:26:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 260061 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9HCQb3X023353 for ; Sun, 17 Oct 2010 12:26:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753474Ab0JQM0a (ORCPT ); Sun, 17 Oct 2010 08:26:30 -0400 Received: from smtp-vbr7.xs4all.nl ([194.109.24.27]:3578 "EHLO smtp-vbr7.xs4all.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753045Ab0JQM03 (ORCPT ); Sun, 17 Oct 2010 08:26:29 -0400 Received: from localhost (186.84-48-119.nextgentel.com [84.48.119.186]) by smtp-vbr7.xs4all.nl (8.13.8/8.13.8) with ESMTP id o9HCQNmm051409 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Sun, 17 Oct 2010 14:26:24 +0200 (CEST) (envelope-from hverkuil@xs4all.nl) Message-Id: <49e7400bcbcc4412b77216bb061db1b57cb3b882.1287318143.git.hverkuil@xs4all.nl> From: Hans Verkuil Date: Sun, 17 Oct 2010 14:26:18 +0200 Subject: [RFC PATCH] radio-mr800: locking fixes To: linux-media@vger.kernel.org Cc: David Ellingsworth X-Virus-Scanned: by XS4ALL Virus Scanner Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Sun, 17 Oct 2010 12:26:53 +0000 (UTC) diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 2f56b26..b540e80 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; }