msm: iommu: Support alternate core clocks
Refactor the IOMMU clock control code to always require a
core clock as well as an interface clock. Add support for
an optional alternate core clock and update device tree
bindings accordingly. Clean up the probe function to remove
needless enabling / disabling of clocks.
Change-Id: I4d744ffabc1e6fb123bacfda324f64408257cb25
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/drivers/iommu/msm_iommu_dev-v2.c b/drivers/iommu/msm_iommu_dev-v2.c
index 14ed5d9..8c26f95 100644
--- a/drivers/iommu/msm_iommu_dev-v2.c
+++ b/drivers/iommu/msm_iommu_dev-v2.c
@@ -69,7 +69,7 @@
{
struct msm_iommu_drvdata *drvdata;
struct resource *r;
- int ret;
+ int ret, needs_alt_core_clk;
if (msm_iommu_root_dev == pdev)
return 0;
@@ -93,55 +93,42 @@
if (IS_ERR(drvdata->gdsc))
return -EINVAL;
- drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
+ drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
if (IS_ERR(drvdata->pclk))
return PTR_ERR(drvdata->pclk);
- ret = clk_prepare_enable(drvdata->pclk);
- if (ret)
- goto fail_enable;
+ drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
+ if (IS_ERR(drvdata->clk))
+ return PTR_ERR(drvdata->clk);
- drvdata->clk = clk_get(&pdev->dev, "core_clk");
- if (!IS_ERR(drvdata->clk)) {
- if (clk_get_rate(drvdata->clk) == 0) {
- ret = clk_round_rate(drvdata->clk, 1);
- clk_set_rate(drvdata->clk, ret);
- }
+ needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
+ "qcom,needs-alt-core-clk");
+ if (needs_alt_core_clk) {
+ drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
+ if (IS_ERR(drvdata->aclk))
+ return PTR_ERR(drvdata->aclk);
+ }
- ret = clk_prepare_enable(drvdata->clk);
- if (ret) {
- clk_put(drvdata->clk);
- goto fail_pclk;
- }
- } else
- drvdata->clk = NULL;
+ if (clk_get_rate(drvdata->clk) == 0) {
+ ret = clk_round_rate(drvdata->clk, 1);
+ clk_set_rate(drvdata->clk, ret);
+ }
+
+ if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
+ ret = clk_round_rate(drvdata->aclk, 1);
+ clk_set_rate(drvdata->aclk, ret);
+ }
ret = msm_iommu_parse_dt(pdev, drvdata);
if (ret)
- goto fail_clk;
+ return ret;
pr_info("device %s mapped at %p, with %d ctx banks\n",
drvdata->name, drvdata->base, drvdata->ncb);
platform_set_drvdata(pdev, drvdata);
- if (drvdata->clk)
- clk_disable_unprepare(drvdata->clk);
-
- clk_disable_unprepare(drvdata->pclk);
-
return 0;
-
-fail_clk:
- if (drvdata->clk) {
- clk_disable_unprepare(drvdata->clk);
- clk_put(drvdata->clk);
- }
-fail_pclk:
- clk_disable_unprepare(drvdata->pclk);
-fail_enable:
- clk_put(drvdata->pclk);
- return ret;
}
static int __devexit msm_iommu_remove(struct platform_device *pdev)