aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:46:09 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:46:09 -0400
commit4f9fb5ed020324d6c151db34460df572b0fdc491 (patch)
treed91ab3117e89c674f2f1bcc897a1b86d6c761154 /drivers
parente26b31449142a18512b57dbea515af234992ba7c (diff)
V4L/DVB: soc-camera: add runtime pm support for subdevices
To save power soc-camera powers subdevices down, when they are not in use, if this is supported by the platform. However, the V4L standard dictates, that video nodes shall preserve configuration between uses. This requires runtime power management, which is implemented by this patch. It allows subdevice drivers to specify their runtime power-management methods, by assigning a type to the video device. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/soc_camera.c18
1 files changed, 17 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