aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/meson/meson_dw_hdmi.c')
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 29a8ff41595d..aad75a22dc33 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -145,8 +145,6 @@ struct meson_dw_hdmi {
145 struct reset_control *hdmitx_apb; 145 struct reset_control *hdmitx_apb;
146 struct reset_control *hdmitx_ctrl; 146 struct reset_control *hdmitx_ctrl;
147 struct reset_control *hdmitx_phy; 147 struct reset_control *hdmitx_phy;
148 struct clk *hdmi_pclk;
149 struct clk *venci_clk;
150 struct regulator *hdmi_supply; 148 struct regulator *hdmi_supply;
151 u32 irq_stat; 149 u32 irq_stat;
152 struct dw_hdmi *hdmi; 150 struct dw_hdmi *hdmi;
@@ -941,6 +939,34 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
941 939
942} 940}
943 941
942static void meson_disable_regulator(void *data)
943{
944 regulator_disable(data);
945}
946
947static void meson_disable_clk(void *data)
948{
949 clk_disable_unprepare(data);
950}
951
952static int meson_enable_clk(struct device *dev, char *name)
953{
954 struct clk *clk;
955 int ret;
956
957 clk = devm_clk_get(dev, name);
958 if (IS_ERR(clk)) {
959 dev_err(dev, "Unable to get %s pclk\n", name);
960 return PTR_ERR(clk);
961 }
962
963 ret = clk_prepare_enable(clk);
964 if (!ret)
965 ret = devm_add_action_or_reset(dev, meson_disable_clk, clk);
966
967 return ret;
968}
969
944static int meson_dw_hdmi_bind(struct device *dev, struct device *master, 970static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
945 void *data) 971 void *data)
946{ 972{
@@ -989,6 +1015,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
989 ret = regulator_enable(meson_dw_hdmi->hdmi_supply); 1015 ret = regulator_enable(meson_dw_hdmi->hdmi_supply);
990 if (ret) 1016 if (ret)
991 return ret; 1017 return ret;
1018 ret = devm_add_action_or_reset(dev, meson_disable_regulator,
1019 meson_dw_hdmi->hdmi_supply);
1020 if (ret)
1021 return ret;
992 } 1022 }
993 1023
994 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, 1024 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,
@@ -1017,19 +1047,17 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
1017 if (IS_ERR(meson_dw_hdmi->hdmitx)) 1047 if (IS_ERR(meson_dw_hdmi->hdmitx))
1018 return PTR_ERR(meson_dw_hdmi->hdmitx); 1048 return PTR_ERR(meson_dw_hdmi->hdmitx);
1019 1049
1020 meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); 1050 ret = meson_enable_clk(dev, "isfr");
1021 if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { 1051 if (ret)
1022 dev_err(dev, "Unable to get HDMI pclk\n"); 1052 return ret;
1023 return PTR_ERR(meson_dw_hdmi->hdmi_pclk);
1024 }
1025 clk_prepare_enable(meson_dw_hdmi->hdmi_pclk);
1026 1053
1027 meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); 1054 ret = meson_enable_clk(dev, "iahb");
1028 if (IS_ERR(meson_dw_hdmi->venci_clk)) { 1055 if (ret)
1029 dev_err(dev, "Unable to get venci clk\n"); 1056 return ret;
1030 return PTR_ERR(meson_dw_hdmi->venci_clk); 1057
1031 } 1058 ret = meson_enable_clk(dev, "venci");
1032 clk_prepare_enable(meson_dw_hdmi->venci_clk); 1059 if (ret)
1060 return ret;
1033 1061
1034 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, 1062 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi,
1035 &meson_dw_hdmi_regmap_config); 1063 &meson_dw_hdmi_regmap_config);
@@ -1062,10 +1090,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
1062 1090
1063 encoder->possible_crtcs = BIT(0); 1091 encoder->possible_crtcs = BIT(0);
1064 1092
1065 DRM_DEBUG_DRIVER("encoder initialized\n");
1066
1067 meson_dw_hdmi_init(meson_dw_hdmi); 1093 meson_dw_hdmi_init(meson_dw_hdmi);
1068 1094
1095 DRM_DEBUG_DRIVER("encoder initialized\n");
1096
1069 /* Bridge / Connector */ 1097 /* Bridge / Connector */
1070 1098
1071 dw_plat_data->priv_data = meson_dw_hdmi; 1099 dw_plat_data->priv_data = meson_dw_hdmi;