diff options
-rw-r--r-- | drivers/media/video/soc_camera.c | 18 | ||||
-rw-r--r-- | include/media/soc_camera.h | 8 |
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 | */ |
415 | esfmt: | 421 | esfmt: |
422 | pm_runtime_disable(&icd->vdev->dev); | ||
423 | eresume: | ||
416 | ici->ops->remove(icd); | 424 | ici->ops->remove(icd); |
417 | eiciadd: | 425 | eiciadd: |
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 | */ |
1320 | static int soc_camera_video_start(struct soc_camera_device *icd) | 1332 | static 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, | |||
284 | extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, | 284 | extern 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> | ||
289 | static 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 |