ASoC: Samsung: i2s: make sure the i2s bus clock is enabled before starting operation
authorInha Song <ideal.song@samsung.com>
Wed, 20 Aug 2014 04:45:38 +0000 (13:45 +0900)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 03:00:43 +0000 (12:00 +0900)
This patch add i2s bus clock enable/disable function. If boards does not have
Audio Sub System, seperate clock is necessary for i2s bus control. This patch
should not effect Exynos4 SoC boards.

Change-Id: Ibcc696767526b3bafaa02b08eec2150410e296c8
Signed-off-by: Inha Song <ideal.song@samsung.com>
sound/soc/samsung/i2s.c

index 95fab0f..bce311d 100644 (file)
@@ -1005,6 +1005,14 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
                        dev_err(&i2s->pdev->dev, "failed to set clock hierachy.\n");
                        return ret;
                }
+       } else {
+               i2s->bus_clk = devm_clk_get(&i2s->pdev->dev, "iis");
+               if (IS_ERR(i2s->bus_clk)) {
+                       dev_err(&i2s->pdev->dev, "failed to get i2s0_bus gate\n");
+                       return PTR_ERR(i2s->bus_clk);
+               }
+
+               clk_prepare_enable(i2s->bus_clk);
        }
 
        if (other) {
@@ -1053,10 +1061,16 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
                        clk_put(i2s->op_clk);
                }
 
+               if (!IS_ERR(i2s->bus_clk)) {
+                       clk_disable_unprepare(i2s->bus_clk);
+                       clk_put(i2s->bus_clk);
+               }
+
                iounmap(i2s->addr);
        }
 
        i2s->op_clk = ERR_PTR(-EINVAL);
+       i2s->bus_clk = ERR_PTR(-EINVAL);
 
        return 0;
 }
@@ -1149,6 +1163,9 @@ static int i2s_runtime_suspend(struct device *dev)
        if (!IS_ERR(i2s->op_clk))
                clk_disable_unprepare(i2s->op_clk);
 
+       if (!IS_ERR(i2s->bus_clk))
+               clk_disable_unprepare(i2s->bus_clk);
+
        return 0;
 }
 
@@ -1159,6 +1176,9 @@ static int i2s_runtime_resume(struct device *dev)
        if (!IS_ERR(i2s->op_clk))
                clk_prepare_enable(i2s->op_clk);
 
+       if (!IS_ERR(i2s->bus_clk))
+               clk_prepare_enable(i2s->bus_clk);
+
        return 0;
 }
 #endif /* CONFIG_PM_RUNTIME */
@@ -1247,10 +1267,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                }
        }
 
-       pri_dai->bus_clk = devm_clk_get(&pdev->dev, "iis");
-       if (!IS_ERR(pri_dai->bus_clk))
-               clk_prepare_enable(pri_dai->bus_clk);
-
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
@@ -1342,9 +1358,6 @@ static int samsung_i2s_remove(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                if (res)
                        release_mem_region(res->start, resource_size(res));
-
-               if (!IS_ERR(i2s->bus_clk))
-                       clk_disable_unprepare(i2s->bus_clk);
        }
 
        i2s->pri_dai = NULL;