浏览代码

disp: msm: dp: check for dp link clocks before accessing dp registers

Add safety checks to check for dp link and core clocks before accessing
the main control registers during dp teardown or dp setup.

Change-Id: Ic80050b7c1cec59d7fc27a1c5f12fa1b244f86fb
Signed-off-by: Vara Reddy <[email protected]>
Vara Reddy 3 年之前
父节点
当前提交
c57fe2034a
共有 3 个文件被更改,包括 36 次插入0 次删除
  1. 10 0
      msm/dp/dp_ctrl.c
  2. 24 0
      msm/dp/dp_power.c
  3. 2 0
      msm/dp/dp_power.h

+ 10 - 0
msm/dp/dp_ctrl.c

@@ -165,6 +165,16 @@ trigger_idle:
 static void dp_ctrl_configure_source_link_params(struct dp_ctrl_private *ctrl,
 		bool enable)
 {
+	if (!ctrl->power->clk_status(ctrl->power, DP_LINK_PM)) {
+		DP_WARN("DP link clocks are off\n");
+		return;
+	}
+
+	if (!ctrl->power->clk_status(ctrl->power, DP_CORE_PM)) {
+		DP_WARN("DP core clocks are off\n");
+		return;
+	}
+
 	if (enable) {
 		ctrl->catalog->lane_mapping(ctrl->catalog, ctrl->orientation,
 						ctrl->parser->l_map);

+ 24 - 0
msm/dp/dp_power.c

@@ -382,6 +382,29 @@ error:
 	return rc;
 }
 
+static bool dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
+{
+	struct dp_power_private *power;
+
+	if (!dp_power) {
+		DP_ERR("invalid power data\n");
+		return false;
+	}
+
+	power = container_of(dp_power, struct dp_power_private, dp_power);
+
+	if (pm_type == DP_LINK_PM)
+		return power->link_clks_on;
+	else if (pm_type == DP_CORE_PM)
+		return power->core_clks_on;
+	else if (pm_type == DP_STREAM0_PM)
+		return power->strm0_clks_on;
+	else if (pm_type == DP_STREAM1_PM)
+		return power->strm1_clks_on;
+	else
+		return false;
+}
+
 static int dp_power_request_gpios(struct dp_power_private *power)
 {
 	int rc = 0, i;
@@ -739,6 +762,7 @@ struct dp_power *dp_power_get(struct dp_parser *parser, struct dp_pll *pll)
 	dp_power->init = dp_power_init;
 	dp_power->deinit = dp_power_deinit;
 	dp_power->clk_enable = dp_power_clk_enable;
+	dp_power->clk_status = dp_power_clk_status;
 	dp_power->set_pixel_clk_parent = dp_power_set_pixel_clk_parent;
 	dp_power->clk_get_rate = dp_power_clk_get_rate;
 	dp_power->power_client_init = dp_power_client_init;

+ 2 - 0
msm/dp/dp_power.h

@@ -16,6 +16,7 @@
  * @init: initializes the regulators/core clocks/GPIOs/pinctrl
  * @deinit: turns off the regulators/core clocks/GPIOs/pinctrl
  * @clk_enable: enable/disable the DP clocks
+ * @clk_status: check for clock status
  * @set_pixel_clk_parent: set the parent of DP pixel clock
  * @clk_get_rate: get the current rate for provided clk_name
  * @power_client_init: configures clocks and regulators
@@ -29,6 +30,7 @@ struct dp_power {
 	int (*deinit)(struct dp_power *power);
 	int (*clk_enable)(struct dp_power *power, enum dp_pm_type pm_type,
 				bool enable);
+	bool (*clk_status)(struct dp_power *power, enum dp_pm_type pm_type);
 	int (*set_pixel_clk_parent)(struct dp_power *power, u32 stream_id);
 	u64 (*clk_get_rate)(struct dp_power *power, char *clk_name);
 	int (*power_client_init)(struct dp_power *power,