Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ba5ace1 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar Committed by Tatenda Chipeperekwa
Browse files

drm/msm/dp: protect power on/off functionalities with mutex



In case of multiple threads trying to power on/off DP driver
simultaneously, un-clocked register access may happen. Use
session_lock in all conditions to avoid such scenario.

Change-Id: I6d8f82b3c37bf54965176dae50e0f9dca5343e2e
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent 320451eb
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -631,7 +631,7 @@ static void dp_display_host_deinit(struct dp_display_private *dp)

static int dp_display_process_hpd_high(struct dp_display_private *dp)
{
	int rc = 0;
	int rc = -EINVAL;

	mutex_lock(&dp->session_lock);

@@ -643,7 +643,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
	}

	dp->is_connected = true;
	mutex_unlock(&dp->session_lock);

	dp->dp_display.max_pclk_khz = min(dp->parser->max_pclk_khz,
					dp->debug->max_pclk_khz);
@@ -665,9 +664,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
	 * ENOTCONN --> no downstream device connected
	 */
	if (rc == -ETIMEDOUT || rc == -ENOTCONN) {
		mutex_lock(&dp->session_lock);
		dp->is_connected = false;
		mutex_unlock(&dp->session_lock);
		goto end;
	}

@@ -676,22 +673,22 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)

	dp_display_process_mst_hpd_high(dp, false);

	mutex_lock(&dp->session_lock);
	rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active,
				dp->panel->fec_en, false);
	if (rc) {
		dp->is_connected = false;
		mutex_unlock(&dp->session_lock);
		goto end;
	}
	mutex_unlock(&dp->session_lock);

	dp->process_hpd_connect = false;

	dp_display_process_mst_hpd_high(dp, true);
end:
	mutex_unlock(&dp->session_lock);

	if (!rc)
		dp_display_send_hpd_notification(dp);
end:

	return rc;
}

@@ -758,6 +755,7 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
			goto end;
	}

	mutex_lock(&dp->session_lock);
	dp_display_host_init(dp);

	/* check for hpd high */
@@ -765,7 +763,7 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
		queue_work(dp->wq, &dp->connect_work);
	else
		dp->process_hpd_connect = true;

	mutex_unlock(&dp->session_lock);
end:
	return rc;
}
@@ -884,8 +882,10 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
		goto end;
	}

	if (dp->debug->psm_enabled)
	mutex_lock(&dp->session_lock);
	if (dp->debug->psm_enabled && dp->core_initialized)
		dp->link->psm_config(dp->link, &dp->panel->link_info, true);
	mutex_unlock(&dp->session_lock);

	dp_display_disconnect_sync(dp);

@@ -934,11 +934,19 @@ static void dp_display_attention_work(struct work_struct *work)
	struct dp_display_private *dp = container_of(work,
			struct dp_display_private, attention_work);

	if (dp->debug->mst_hpd_sim)
	mutex_lock(&dp->session_lock);

	if (dp->debug->mst_hpd_sim || !dp->core_initialized) {
		mutex_unlock(&dp->session_lock);
		goto mst_attention;
	}

	if (dp->link->process_request(dp->link))
	if (dp->link->process_request(dp->link)) {
		mutex_unlock(&dp->session_lock);
		goto cp_irq;
	}

	mutex_unlock(&dp->session_lock);

	if (dp->link->sink_request & DS_PORT_STATUS_CHANGED) {
		if (dp_display_is_sink_count_zero(dp)) {