diff options
author | Robby Cai <r63905@freescale.com> | 2014-07-08 02:26:19 -0400 |
---|---|---|
committer | Robby Cai <r63905@freescale.com> | 2014-07-08 05:14:05 -0400 |
commit | 90666b1b59a32f5e5071b4f940895cdf7327d811 (patch) | |
tree | 418169eb7352ac10b3d8a5777514054f854a234d | |
parent | 7bd8af01b6e51cf86afd453777d095fd4991261b (diff) |
ENGR00321733 csi: imx6sx: reinitialize csi when resume
The CSI will be reset to initial state because dispmix takes effect
and power off specific modules when suspend. Hence the reinitialization
is needed when resume to make it work properly, otherwise the captured
images are not correct.
Signed-off-by: Robby Cai <r63905@freescale.com>
(cherry picked from commit a9705bae9405bbf68a5db13a97e1d94e4ba15683)
-rw-r--r-- | drivers/media/platform/mxc/capture/fsl_csi.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/media/platform/mxc/capture/fsl_csi.c b/drivers/media/platform/mxc/capture/fsl_csi.c index 602899d70ce0..01212348284b 100644 --- a/drivers/media/platform/mxc/capture/fsl_csi.c +++ b/drivers/media/platform/mxc/capture/fsl_csi.c | |||
@@ -419,6 +419,8 @@ static int csi_probe(struct platform_device *pdev) | |||
419 | return PTR_ERR(dcic_clk); | 419 | return PTR_ERR(dcic_clk); |
420 | } | 420 | } |
421 | 421 | ||
422 | platform_set_drvdata(pdev, csi); | ||
423 | |||
422 | csi_clk_enable(); | 424 | csi_clk_enable(); |
423 | csihw_reset(csi); | 425 | csihw_reset(csi); |
424 | csi_init_interface(csi); | 426 | csi_init_interface(csi); |
@@ -431,13 +433,52 @@ err: | |||
431 | 433 | ||
432 | static int csi_remove(struct platform_device *pdev) | 434 | static int csi_remove(struct platform_device *pdev) |
433 | { | 435 | { |
436 | struct csi_soc *csi = platform_get_drvdata(pdev); | ||
437 | |||
438 | csi->online = false; | ||
439 | platform_set_drvdata(pdev, NULL); | ||
440 | |||
434 | return 0; | 441 | return 0; |
435 | } | 442 | } |
436 | 443 | ||
444 | #ifdef CONFIG_PM_SLEEP | ||
445 | static int csi_suspend(struct device *dev) | ||
446 | { | ||
447 | struct csi_soc *csi = dev_get_drvdata(dev); | ||
448 | |||
449 | csi->online = false; | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int csi_resume(struct device *dev) | ||
455 | { | ||
456 | struct csi_soc *csi = dev_get_drvdata(dev); | ||
457 | |||
458 | csi_clk_enable(); | ||
459 | csihw_reset(csi); | ||
460 | csi_init_interface(csi); | ||
461 | csi_dmareq_rff_disable(csi); | ||
462 | csi_clk_disable(); | ||
463 | |||
464 | csi->online = true; | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | #else | ||
469 | #define csi_suspend NULL | ||
470 | #define csi_resume NULL | ||
471 | #endif | ||
472 | |||
473 | static const struct dev_pm_ops csi_pm_ops = { | ||
474 | SET_SYSTEM_SLEEP_PM_OPS(csi_suspend, csi_resume) | ||
475 | }; | ||
476 | |||
437 | static struct platform_driver csi_driver = { | 477 | static struct platform_driver csi_driver = { |
438 | .driver = { | 478 | .driver = { |
439 | .name = "fsl_csi", | 479 | .name = "fsl_csi", |
440 | .of_match_table = of_match_ptr(fsl_csi_dt_ids), | 480 | .of_match_table = of_match_ptr(fsl_csi_dt_ids), |
481 | .pm = &csi_pm_ops, | ||
441 | }, | 482 | }, |
442 | .probe = csi_probe, | 483 | .probe = csi_probe, |
443 | .remove = csi_remove, | 484 | .remove = csi_remove, |