summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/phy/dsi_phy.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 5f153b683521..69214447f757 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -3,6 +3,7 @@
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
+#include <linux/clk-provider.h>
#include <linux/platform_device.h>
#include "dsi_phy.h"
@@ -652,6 +653,14 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
if (!match)
return -ENODEV;
+ phy->provided_clocks = devm_kzalloc(dev,
+ struct_size(phy->provided_clocks, hws, NUM_PROVIDED_CLKS),
+ GFP_KERNEL);
+ if (!phy->provided_clocks)
+ return -ENOMEM;
+
+ phy->provided_clocks->num = NUM_PROVIDED_CLKS;
+
phy->cfg = match->data;
phy->pdev = pdev;
@@ -719,6 +728,13 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
}
}
+ ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+ phy->provided_clocks);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
+ goto fail;
+ }
+
dsi_phy_disable_resource(phy);
platform_set_drvdata(pdev, phy);
@@ -726,6 +742,12 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
return 0;
fail:
+ if (phy->pll) {
+ of_clk_del_provider(dev->of_node);
+ msm_dsi_pll_destroy(phy->pll);
+ phy->pll = NULL;
+ }
+
return ret;
}
@@ -734,6 +756,7 @@ static int dsi_phy_driver_remove(struct platform_device *pdev)
struct msm_dsi_phy *phy = platform_get_drvdata(pdev);
if (phy && phy->pll) {
+ of_clk_del_provider(pdev->dev.of_node);
msm_dsi_pll_destroy(phy->pll);
phy->pll = NULL;
}
@@ -851,3 +874,14 @@ void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
if (phy)
phy->usecase = uc;
}
+
+int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
+ struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
+{
+ if (byte_clk_provider)
+ *byte_clk_provider = phy->provided_clocks->hws[DSI_BYTE_PLL_CLK]->clk;
+ if (pixel_clk_provider)
+ *pixel_clk_provider = phy->provided_clocks->hws[DSI_PIXEL_PLL_CLK]->clk;
+
+ return -EINVAL;
+}