aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/soc_camera.c18
-rw-r--r--include/media/soc_camera.h8
2 files changed, 25 insertions, 1 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a24174ddec46..0c65031f3d82 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,6 +25,7 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/pm_runtime.h>
28#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
29 30
30#include <media/soc_camera.h> 31#include <media/soc_camera.h>
@@ -388,6 +389,11 @@ static int soc_camera_open(struct file *file)
388 goto eiciadd; 389 goto eiciadd;
389 } 390 }
390 391
392 pm_runtime_enable(&icd->vdev->dev);
393 ret = pm_runtime_resume(&icd->vdev->dev);
394 if (ret < 0 && ret != -ENOSYS)
395 goto eresume;
396
391 /* 397 /*
392 * Try to configure with default parameters. Notice: this is the 398 * Try to configure with default parameters. Notice: this is the
393 * very first open, so, we cannot race against other calls, 399 * very first open, so, we cannot race against other calls,
@@ -409,10 +415,12 @@ static int soc_camera_open(struct file *file)
409 return 0; 415 return 0;
410 416
411 /* 417 /*
412 * First five errors are entered with the .video_lock held 418 * First four errors are entered with the .video_lock held
413 * and use_count == 1 419 * and use_count == 1
414 */ 420 */
415esfmt: 421esfmt:
422 pm_runtime_disable(&icd->vdev->dev);
423eresume:
416 ici->ops->remove(icd); 424 ici->ops->remove(icd);
417eiciadd: 425eiciadd:
418 if (icl->power) 426 if (icl->power)
@@ -437,7 +445,11 @@ static int soc_camera_close(struct file *file)
437 if (!icd->use_count) { 445 if (!icd->use_count) {
438 struct soc_camera_link *icl = to_soc_camera_link(icd); 446 struct soc_camera_link *icl = to_soc_camera_link(icd);
439 447
448 pm_runtime_suspend(&icd->vdev->dev);
449 pm_runtime_disable(&icd->vdev->dev);
450
440 ici->ops->remove(icd); 451 ici->ops->remove(icd);
452
441 if (icl->power) 453 if (icl->power)
442 icl->power(icd->pdev, 0); 454 icl->power(icd->pdev, 0);
443 } 455 }
@@ -1319,6 +1331,7 @@ static int video_dev_create(struct soc_camera_device *icd)
1319 */ 1331 */
1320static int soc_camera_video_start(struct soc_camera_device *icd) 1332static int soc_camera_video_start(struct soc_camera_device *icd)
1321{ 1333{
1334 struct device_type *type = icd->vdev->dev.type;
1322 int ret; 1335 int ret;
1323 1336
1324 if (!icd->dev.parent) 1337 if (!icd->dev.parent)
@@ -1335,6 +1348,9 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
1335 return ret; 1348 return ret;
1336 } 1349 }
1337 1350
1351 /* Restore device type, possibly set by the subdevice driver */
1352 icd->vdev->dev.type = type;
1353
1338 return 0; 1354 return 0;
1339} 1355}
1340 1356
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 5a173652cf4a..c9a5bbfa6ab5 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -284,4 +284,12 @@ static inline void soc_camera_limit_side(int *start, int *length,
284extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 284extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
285 unsigned long flags); 285 unsigned long flags);
286 286
287/* This is only temporary here - until v4l2-subdev begins to link to video_device */
288#include <linux/i2c.h>
289static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *client)
290{
291 struct soc_camera_device *icd = client->dev.platform_data;
292 return icd->vdev;
293}
294
287#endif 295#endif