diff options
| author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-06-14 09:44:30 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-06-19 08:06:01 -0400 |
| commit | 722a860ecb29aa34ec6f7d7f32b949209e86a2f3 (patch) | |
| tree | 10163feada5e85e889a5d681282b2f5a46b5d358 | |
| parent | a908eb9936ba06678720226feed891d01827066f (diff) | |
[media] exynos4-is: Fix FIMC-IS clocks initialization
The ISP clock register content is not preserved over the ISP power domain
off/on cycle. Instead of setting the clock frequencies once at probe time
the clock rates set up is moved to the runtime_resume handler, which is
invoked after the related power domain is already enabled, ensuring the
clocks are properly configured when the device is actively used.
This fixes the FIMC-IS malfunctions and STREAM ON timeout errors accuring
on some boards:
[ 59.860000] fimc_is_general_irq_handler:583 ISR_NDONE: 5: 0x800003e8, IS_ERROR_UNKNOWN
[ 59.860000] fimc_is_general_irq_handler:586 IS_ERROR_TIME_OUT
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/platform/exynos4-is/fimc-is.c | 26 | ||||
| -rw-r--r-- | drivers/media/platform/exynos4-is/fimc-is.h | 1 |
2 files changed, 8 insertions, 19 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 520e4398b69c..0741945b79ed 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c | |||
| @@ -834,23 +834,11 @@ static int fimc_is_probe(struct platform_device *pdev) | |||
| 834 | goto err_clk; | 834 | goto err_clk; |
| 835 | } | 835 | } |
| 836 | pm_runtime_enable(dev); | 836 | pm_runtime_enable(dev); |
| 837 | /* | ||
| 838 | * Enable only the ISP power domain, keep FIMC-IS clocks off until | ||
| 839 | * the whole clock tree is configured. The ISP power domain needs | ||
| 840 | * be active in order to acces any CMU_ISP clock registers. | ||
| 841 | */ | ||
| 842 | ret = pm_runtime_get_sync(dev); | ||
| 843 | if (ret < 0) | ||
| 844 | goto err_irq; | ||
| 845 | |||
| 846 | ret = fimc_is_setup_clocks(is); | ||
| 847 | pm_runtime_put_sync(dev); | ||
| 848 | 837 | ||
| 838 | ret = pm_runtime_get_sync(dev); | ||
| 849 | if (ret < 0) | 839 | if (ret < 0) |
| 850 | goto err_irq; | 840 | goto err_irq; |
| 851 | 841 | ||
| 852 | is->clk_init = true; | ||
| 853 | |||
| 854 | is->alloc_ctx = vb2_dma_contig_init_ctx(dev); | 842 | is->alloc_ctx = vb2_dma_contig_init_ctx(dev); |
| 855 | if (IS_ERR(is->alloc_ctx)) { | 843 | if (IS_ERR(is->alloc_ctx)) { |
| 856 | ret = PTR_ERR(is->alloc_ctx); | 844 | ret = PTR_ERR(is->alloc_ctx); |
| @@ -872,6 +860,8 @@ static int fimc_is_probe(struct platform_device *pdev) | |||
| 872 | if (ret < 0) | 860 | if (ret < 0) |
| 873 | goto err_dfs; | 861 | goto err_dfs; |
| 874 | 862 | ||
| 863 | pm_runtime_put_sync(dev); | ||
| 864 | |||
| 875 | dev_dbg(dev, "FIMC-IS registered successfully\n"); | 865 | dev_dbg(dev, "FIMC-IS registered successfully\n"); |
| 876 | return 0; | 866 | return 0; |
| 877 | 867 | ||
| @@ -891,9 +881,11 @@ err_clk: | |||
| 891 | static int fimc_is_runtime_resume(struct device *dev) | 881 | static int fimc_is_runtime_resume(struct device *dev) |
| 892 | { | 882 | { |
| 893 | struct fimc_is *is = dev_get_drvdata(dev); | 883 | struct fimc_is *is = dev_get_drvdata(dev); |
| 884 | int ret; | ||
| 894 | 885 | ||
| 895 | if (!is->clk_init) | 886 | ret = fimc_is_setup_clocks(is); |
| 896 | return 0; | 887 | if (ret) |
| 888 | return ret; | ||
| 897 | 889 | ||
| 898 | return fimc_is_enable_clocks(is); | 890 | return fimc_is_enable_clocks(is); |
| 899 | } | 891 | } |
| @@ -902,9 +894,7 @@ static int fimc_is_runtime_suspend(struct device *dev) | |||
| 902 | { | 894 | { |
| 903 | struct fimc_is *is = dev_get_drvdata(dev); | 895 | struct fimc_is *is = dev_get_drvdata(dev); |
| 904 | 896 | ||
| 905 | if (is->clk_init) | 897 | fimc_is_disable_clocks(is); |
| 906 | fimc_is_disable_clocks(is); | ||
| 907 | |||
| 908 | return 0; | 898 | return 0; |
| 909 | } | 899 | } |
| 910 | 900 | ||
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h index 606a7c9fe526..d7db133b493f 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.h +++ b/drivers/media/platform/exynos4-is/fimc-is.h | |||
| @@ -264,7 +264,6 @@ struct fimc_is { | |||
| 264 | spinlock_t slock; | 264 | spinlock_t slock; |
| 265 | 265 | ||
| 266 | struct clk *clocks[ISS_CLKS_MAX]; | 266 | struct clk *clocks[ISS_CLKS_MAX]; |
| 267 | bool clk_init; | ||
| 268 | void __iomem *regs; | 267 | void __iomem *regs; |
| 269 | void __iomem *pmu_regs; | 268 | void __iomem *pmu_regs; |
| 270 | int irq; | 269 | int irq; |
