summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeata Michalska <b.michalska@samsung.com>2014-07-14 14:27:29 +0200
committerSylwester Nawrocki <s.nawrocki@samsung.com>2014-11-27 03:40:06 -0800
commitdeaf90b018f621ab04860e4b2090b3e89b908682 (patch)
tree73f136d58402ca7f9531925046f57c56bbcb91cf
parentc4afb1e0893f040416c4bef328edad5d2d4a97a5 (diff)
downloadlinux-3.10-deaf90b018f621ab04860e4b2090b3e89b908682.tar.gz
linux-3.10-deaf90b018f621ab04860e4b2090b3e89b908682.tar.bz2
linux-3.10-deaf90b018f621ab04860e4b2090b3e89b908682.zip
exynos: mipi-csis: Fix clock handling for exynos3250
In case of Exynos3250 only gate clock is required thus all the remaining mipi-csis clocks are considered as optional. Signed-off-by: Beata Michalska <b.michalska@samsung.com> Change-Id: Ibadffe49739add39f156737cbb723b24a5dd4ff5
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 01102f82f37..4d697486e39 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -134,16 +134,16 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
#define S5PCSIS_PKTDATA_SIZE SZ_4K
enum {
- CSIS_CLK_BUS,
CSIS_CLK_GATE,
+ CSIS_CLK_BUS,
CSIS_CLK_MUX,
CSIS_CLK_PARENT,
};
static char *csi_clock_name[] = {
- [CSIS_CLK_BUS] = "sclk_csis",
- [CSIS_CLK_GATE] = "csis",
- [CSIS_CLK_MUX] = "mux",
+ [CSIS_CLK_GATE] = "csis",
+ [CSIS_CLK_BUS] = "sclk_csis",
+ [CSIS_CLK_MUX] = "mux",
[CSIS_CLK_PARENT] = "parent",
};
#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
@@ -214,6 +214,7 @@ struct csis_pktbuf {
* @hss_mask: HS-RX settle time mask
* @num_virt_channels: number of available virtual channels
* @num_dlanes_reg: register for data lanes configuration
+ * @sclk_csis IP support for SCLK_CSIS clock
*/
struct csis_drvdata {
u32 interrupt_mask;
@@ -221,6 +222,7 @@ struct csis_drvdata {
u32 hss_mask;
unsigned short num_virt_channels;
unsigned short num_dlanes_reg;
+ unsigned int sclk_csis:1;
};
/**
@@ -461,8 +463,14 @@ static int s5pcsis_get_clocks(struct csis_state *state)
int i, ret;
/* Skip parent and mux clocks for non-dt platforms */
- if (!dev->of_node)
+ if (!dev->of_node) {
num_clocks -= 2;
+ }
+ else {
+ /* Exynos3250 requires only CSIS_CLK_GATE */
+ if (!state->drv_data->sclk_csis)
+ num_clocks = 1;
+ }
for (i = 0; i < NUM_CSIS_CLOCKS; i++)
state->clock[i] = ERR_PTR(-EINVAL);
@@ -489,7 +497,7 @@ err:
static int s5pcsis_setup_clocks(struct csis_state *state)
{
- int ret;
+ int ret = 0;
if (!IS_ERR(state->clock[CSIS_CLK_PARENT])) {
ret = clk_set_parent(state->clock[CSIS_CLK_MUX],
@@ -501,11 +509,14 @@ static int s5pcsis_setup_clocks(struct csis_state *state)
return ret;
}
}
- ret = clk_set_rate(state->clock[CSIS_CLK_BUS],
+ if (state->drv_data->sclk_csis) {
+ ret = clk_set_rate(state->clock[CSIS_CLK_BUS],
state->clk_frequency);
- if (ret < 0)
- return ret;
- return clk_enable(state->clock[CSIS_CLK_BUS]);
+ if (ret < 0)
+ return ret;
+ ret = clk_enable(state->clock[CSIS_CLK_BUS]);
+ }
+ return ret;
}
static void dump_regs(struct csis_state *state, const char *label)
@@ -926,6 +937,7 @@ static const struct csis_drvdata s5pcsis_drvdata[] = {
.hss_mask = EXYNOS3250_DPHYCTRL_HSS_MASK,
.num_dlanes_reg = S5PCSIS_CTRL,
.num_virt_channels = 4,
+ .sclk_csis = 0,
},
[S5PCSIS_EXYNOS4] = {
.interrupt_mask = EXYNOS4_INTMSK_EN_ALL,
@@ -933,6 +945,7 @@ static const struct csis_drvdata s5pcsis_drvdata[] = {
.hss_mask = S5PCSIS_DPHYCTRL_HSS_MASK,
.num_dlanes_reg = S5PCSIS_CONFIG,
.num_virt_channels = 1,
+ .sclk_csis = 1,
},
[S5PCSIS_EXYNOS5] = {
.interrupt_mask = EXYNOS5_INTMSK_EN_ALL,
@@ -940,6 +953,7 @@ static const struct csis_drvdata s5pcsis_drvdata[] = {
.hss_mask = S5PCSIS_DPHYCTRL_HSS_MASK,
.num_dlanes_reg = S5PCSIS_CONFIG,
.num_virt_channels = 1,
+ .sclk_csis = 1,
}
};
@@ -1053,7 +1067,8 @@ static int s5pcsis_probe(struct platform_device *pdev)
return 0;
e_clkdis:
- clk_disable(state->clock[CSIS_CLK_BUS]);
+ if (state->drv_data->sclk_csis)
+ clk_disable(state->clock[CSIS_CLK_BUS]);
e_clkput:
s5pcsis_put_clocks(state);
return ret;
@@ -1157,8 +1172,9 @@ static int s5pcsis_remove(struct platform_device *pdev)
struct csis_state *state = sd_to_csis_state(sd);
pm_runtime_disable(&pdev->dev);
- s5pcsis_pm_suspend(&pdev->dev, false);
- clk_disable(state->clock[CSIS_CLK_BUS]);
+ s5pcsis_pm_suspend(&pdev->dev, true);
+ if (state->drv_data->sclk_csis)
+ clk_disable(state->clock[CSIS_CLK_BUS]);
pm_runtime_set_suspended(&pdev->dev);
s5pcsis_put_clocks(state);