summaryrefslogtreecommitdiff
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-05-21 23:27:26 +0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-21 23:27:26 +0400
commitee9a3607fb03e804ddf624544105f4e34260c380 (patch)
treece41b6e0fa10982a306f6c142a92dbf3c9961284 /drivers/media/video/soc_camera.c
parentb492e95be0ae672922f4734acf3f5d35c30be948 (diff)
parentd515e86e639890b33a09390d062b0831664f04a2 (diff)
downloadlinux-ee9a3607fb03e804ddf624544105f4e34260c380.tar.xz
Merge branch 'master' into for-2.6.35
Conflicts: fs/ext3/fsync.c Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a24174ddec46..db1ca0e90d76 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <linux/vmalloc.h>
#include <media/soc_camera.h>
@@ -388,6 +389,11 @@ static int soc_camera_open(struct file *file)
goto eiciadd;
}
+ pm_runtime_enable(&icd->vdev->dev);
+ ret = pm_runtime_resume(&icd->vdev->dev);
+ if (ret < 0 && ret != -ENOSYS)
+ goto eresume;
+
/*
* Try to configure with default parameters. Notice: this is the
* very first open, so, we cannot race against other calls,
@@ -409,10 +415,12 @@ static int soc_camera_open(struct file *file)
return 0;
/*
- * First five errors are entered with the .video_lock held
+ * First four errors are entered with the .video_lock held
* and use_count == 1
*/
esfmt:
+ pm_runtime_disable(&icd->vdev->dev);
+eresume:
ici->ops->remove(icd);
eiciadd:
if (icl->power)
@@ -437,7 +445,11 @@ static int soc_camera_close(struct file *file)
if (!icd->use_count) {
struct soc_camera_link *icl = to_soc_camera_link(icd);
+ pm_runtime_suspend(&icd->vdev->dev);
+ pm_runtime_disable(&icd->vdev->dev);
+
ici->ops->remove(icd);
+
if (icl->power)
icl->power(icd->pdev, 0);
}
@@ -741,8 +753,7 @@ static int soc_camera_g_crop(struct file *file, void *fh,
/*
* According to the V4L2 API, drivers shall not update the struct v4l2_crop
* argument with the actual geometry, instead, the user shall use G_CROP to
- * retrieve it. However, we expect camera host and client drivers to update
- * the argument, which we then use internally, but do not return to the user.
+ * retrieve it.
*/
static int soc_camera_s_crop(struct file *file, void *fh,
struct v4l2_crop *a)
@@ -1319,6 +1330,7 @@ static int video_dev_create(struct soc_camera_device *icd)
*/
static int soc_camera_video_start(struct soc_camera_device *icd)
{
+ struct device_type *type = icd->vdev->dev.type;
int ret;
if (!icd->dev.parent)
@@ -1335,6 +1347,9 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
return ret;
}
+ /* Restore device type, possibly set by the subdevice driver */
+ icd->vdev->dev.type = type;
+
return 0;
}