From patchwork Sat Sep 12 14:48:55 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ellingsworth X-Patchwork-Id: 47072 X-Patchwork-Delegate: dougsland@redhat.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n8CEnBiZ027499 for ; Sat, 12 Sep 2009 14:49:11 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754590AbZILOtG (ORCPT ); Sat, 12 Sep 2009 10:49:06 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754589AbZILOtG (ORCPT ); Sat, 12 Sep 2009 10:49:06 -0400 Received: from qw-out-2122.google.com ([74.125.92.25]:20584 "EHLO qw-out-2122.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754558AbZILOtE (ORCPT ); Sat, 12 Sep 2009 10:49:04 -0400 Received: by qw-out-2122.google.com with SMTP id 9so632867qwb.37 for ; Sat, 12 Sep 2009 07:49:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:message-id:date:from :reply-to:user-agent:mime-version:to:subject:content-type; bh=eh3RDlraHb/DxiOpkUNf2W+ONXsNGBKFbyMOTeKrm7w=; b=jWAVi9H2LTNPRJK80wlD0/x5Ko4i682pi3qvvw9Q4eC74b6W5WRoefhobbcwW+i/Zc a0keJvhj5Vide62i9KseuymkhZXaxG6CJTYjoImQhuRsnFK4A6IgwsGZLMyp129cjsHV ERb27GlvFjOfcY+woUru0SKEVA+sGUPM/dV0Y= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:message-id:date:from:reply-to:user-agent:mime-version:to :subject:content-type; b=aiAdFkFYPowQlO/pNvXl0wWns8hM/lz+T370K4czlI6xQNL6VMrJ5jMw1QCnTPqg8d bsqEIeEvGeIhKI2nAnq0v3C7jI9rlpb58IQEZzhvsscQhctcFnZzQuUGbvoqLwursEeQ aC7gF6dxBLVXJ7rZEdjEFi4l/Yp/qfYJfLaZ4= Received: by 10.224.87.228 with SMTP id x36mr3733681qal.287.1252766945042; Sat, 12 Sep 2009 07:49:05 -0700 (PDT) Received: from ?192.168.10.110? (cpe-71-72-62-249.neo.res.rr.com [71.72.62.249]) by mx.google.com with ESMTPS id 8sm2153157qwj.48.2009.09.12.07.49.02 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 12 Sep 2009 07:49:03 -0700 (PDT) Message-ID: <4AABB4D7.3070903@gmail.com> Date: Sat, 12 Sep 2009 10:48:55 -0400 From: David Ellingsworth Reply-To: david@identd.dyndns.org User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090701) MIME-Version: 1.0 To: linux-media@vger.kernel.org, klimov.linux@gmail.com Subject: [RFC/RFT 01/10] radio-mr800: implement proper locking Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From 1773df59dc8e63ca00a27f5235c293341fd07f36 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Fri, 11 Sep 2009 23:21:17 -0400 Subject: [PATCH 01/10] mr800: implement proper locking Signed-off-by: David Ellingsworth --- drivers/media/radio/radio-mr800.c | 181 ++++++++++++++++++++++--------------- 1 files changed, 106 insertions(+), 75 deletions(-) radio->buffer[1] = 0x55; @@ -186,15 +182,11 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } radio->muted = argument; - mutex_unlock(&radio->lock); - return retval; } @@ -205,11 +197,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) int size; unsigned short freq_send = 0x10 + (freq >> 3) / 25; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -223,10 +211,8 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } /* frequency is calculated from freq_send and placed in first 2 bytes */ radio->buffer[0] = (freq_send >> 8) & 0xff; @@ -240,13 +226,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - return retval; } @@ -255,11 +234,7 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -275,14 +250,11 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) if (retval < 0 || size != BUFFER_LENGTH) { radio->stereo = -1; - mutex_unlock(&radio->lock); return retval; } radio->stereo = 1; - mutex_unlock(&radio->lock); - return retval; } @@ -325,12 +297,18 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); @@ -357,7 +335,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->audmode = V4L2_TUNER_MODE_MONO; v->signal = 0xffff; /* Can't get the signal strength, sad.. */ v->afc = 0; /* Don't know what is this */ - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_tuner - set tuner attributes */ @@ -367,12 +348,18 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* mono/stereo selector */ switch (v->audmode) { @@ -389,10 +376,12 @@ static int vidioc_s_tuner(struct file *file, void *priv, "set stereo failed\n"); break; default: - return -EINVAL; + retval = -EINVAL; } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_frequency - set tuner radio frequency */ @@ -402,19 +391,24 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - mutex_lock(&radio->lock); radio->curfreq = f->frequency; - mutex_unlock(&radio->lock); retval = amradio_setfreq(radio, radio->curfreq); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_frequency - get tuner radio frequency */ @@ -422,14 +416,22 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_queryctrl - enumerate control items */ @@ -449,17 +451,26 @@ static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = radio->muted; - return 0; + retval = 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_ctrl - set the value of a control */ @@ -467,11 +478,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -480,19 +495,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); - return -1; } } else { retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); - return -1; } } - return 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_audio - get audio attributes */ @@ -535,9 +551,14 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - lock_kernel(); + mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } radio->users = 1; radio->muted = 1; @@ -547,8 +568,7 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); radio->users = 0; - unlock_kernel(); - return -EIO; + goto unlock; } retval = amradio_set_stereo(radio, WANT_STEREO); @@ -561,22 +581,25 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - unlock_kernel(); - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /*close device */ static int usb_amradio_close(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; - - if (!radio) - return -ENODEV; + int retval = 0; mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } + radio->users = 0; - mutex_unlock(&radio->lock); if (!radio->removed) { retval = amradio_set_mute(radio, AMRADIO_STOP); @@ -585,7 +608,9 @@ static int usb_amradio_close(struct file *file) "amradio_stop failed\n"); } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* Suspend device - stop device. Need to be checked and fixed */ @@ -594,12 +619,15 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); + mutex_unlock(&radio->lock); return 0; } @@ -609,12 +637,15 @@ static int usb_amradio_resume(struct usb_interface *intf) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) dev_warn(&intf->dev, "amradio_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); + mutex_unlock(&radio->lock); return 0; } From 1773df59dc8e63ca00a27f5235c293341fd07f36 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Fri, 11 Sep 2009 23:21:17 -0400 Subject: [PATCH 01/10] mr800: implement proper locking Signed-off-by: David Ellingsworth --- drivers/media/radio/radio-mr800.c | 181 ++++++++++++++++++++++--------------- 1 files changed, 106 insertions(+), 75 deletions(-) diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 575bf9d..8e96c8a 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -168,11 +168,7 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -186,15 +182,11 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } radio->muted = argument; - mutex_unlock(&radio->lock); - return retval; } @@ -205,11 +197,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) int size; unsigned short freq_send = 0x10 + (freq >> 3) / 25; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -223,10 +211,8 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } /* frequency is calculated from freq_send and placed in first 2 bytes */ radio->buffer[0] = (freq_send >> 8) & 0xff; @@ -240,13 +226,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - return retval; } @@ -255,11 +234,7 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -275,14 +250,11 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) if (retval < 0 || size != BUFFER_LENGTH) { radio->stereo = -1; - mutex_unlock(&radio->lock); return retval; } radio->stereo = 1; - mutex_unlock(&radio->lock); - return retval; } @@ -325,12 +297,18 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); @@ -357,7 +335,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->audmode = V4L2_TUNER_MODE_MONO; v->signal = 0xffff; /* Can't get the signal strength, sad.. */ v->afc = 0; /* Don't know what is this */ - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_tuner - set tuner attributes */ @@ -367,12 +348,18 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* mono/stereo selector */ switch (v->audmode) { @@ -389,10 +376,12 @@ static int vidioc_s_tuner(struct file *file, void *priv, "set stereo failed\n"); break; default: - return -EINVAL; + retval = -EINVAL; } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_frequency - set tuner radio frequency */ @@ -402,19 +391,24 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - mutex_lock(&radio->lock); radio->curfreq = f->frequency; - mutex_unlock(&radio->lock); retval = amradio_setfreq(radio, radio->curfreq); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_frequency - get tuner radio frequency */ @@ -422,14 +416,22 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_queryctrl - enumerate control items */ @@ -449,17 +451,26 @@ static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = radio->muted; - return 0; + retval = 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_ctrl - set the value of a control */ @@ -467,11 +478,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -480,19 +495,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); - return -1; } } else { retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); - return -1; } } - return 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_audio - get audio attributes */ @@ -535,9 +551,14 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - lock_kernel(); + mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } radio->users = 1; radio->muted = 1; @@ -547,8 +568,7 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); radio->users = 0; - unlock_kernel(); - return -EIO; + goto unlock; } retval = amradio_set_stereo(radio, WANT_STEREO); @@ -561,22 +581,25 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - unlock_kernel(); - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /*close device */ static int usb_amradio_close(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; - - if (!radio) - return -ENODEV; + int retval = 0; mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } + radio->users = 0; - mutex_unlock(&radio->lock); if (!radio->removed) { retval = amradio_set_mute(radio, AMRADIO_STOP); @@ -585,7 +608,9 @@ static int usb_amradio_close(struct file *file) "amradio_stop failed\n"); } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* Suspend device - stop device. Need to be checked and fixed */ @@ -594,12 +619,15 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); + mutex_unlock(&radio->lock); return 0; } @@ -609,12 +637,15 @@ static int usb_amradio_resume(struct usb_interface *intf) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) dev_warn(&intf->dev, "amradio_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); + mutex_unlock(&radio->lock); return 0; } -- 1.6.3.3