@@ -378,7 +378,7 @@ void uvc_status_suspend(struct uvc_device *dev)
uvc_status_stop(dev);
}
-int uvc_status_get(struct uvc_device *dev)
+static int _uvc_status_get(struct uvc_device *dev)
{
int ret;
@@ -395,13 +395,41 @@ int uvc_status_get(struct uvc_device *dev)
return 0;
}
-void uvc_status_put(struct uvc_device *dev)
+int uvc_status_get(struct uvc_device *dev)
+{
+ int ret;
+
+ ret = usb_autopm_get_interface(dev->intf);
+ if (ret)
+ return ret;
+
+ ret = _uvc_status_get(dev);
+
+ if (ret)
+ usb_autopm_put_interface(dev->intf);
+
+ return ret;
+}
+
+static int _uvc_status_put(struct uvc_device *dev)
{
guard(mutex)(&dev->status_lock);
if (dev->status_users == 1)
uvc_status_stop(dev);
- WARN_ON(!dev->status_users);
- if (dev->status_users)
- dev->status_users--;
+
+ if (WARN_ON(!dev->status_users))
+ return -EIO;
+
+ dev->status_users--;
+ return 0;
+}
+
+void uvc_status_put(struct uvc_device *dev)
+{
+ int ret;
+
+ ret = _uvc_status_put(dev);
+ if (!ret)
+ usb_autopm_put_interface(dev->intf);
}
@@ -617,20 +617,13 @@ static int uvc_v4l2_open(struct file *file)
stream = video_drvdata(file);
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
- ret = usb_autopm_get_interface(stream->dev->intf);
- if (ret < 0)
- return ret;
-
/* Create the device handle. */
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
- if (handle == NULL) {
- usb_autopm_put_interface(stream->dev->intf);
+ if (!handle)
return -ENOMEM;
- }
ret = uvc_status_get(stream->dev);
if (ret) {
- usb_autopm_put_interface(stream->dev->intf);
kfree(handle);
return ret;
}
@@ -666,8 +659,6 @@ static int uvc_v4l2_release(struct file *file)
file->private_data = NULL;
uvc_status_put(stream->dev);
-
- usb_autopm_put_interface(stream->dev->intf);
return 0;
}
Right now PM operations are always called at the same locations as uvc_status_(get|put). Combine them into uvc_status_(get|put). This simplifies the current code and future PM changes in the driver. Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> --- drivers/media/usb/uvc/uvc_status.c | 38 +++++++++++++++++++++++++++++++++----- drivers/media/usb/uvc/uvc_v4l2.c | 11 +---------- 2 files changed, 34 insertions(+), 15 deletions(-)