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

Commit 9d26a7fb authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: dp: gracefully handle cable disconnect"

parents e66fc6f5 81fc1566
Loading
Loading
Loading
Loading
+66 −14
Original line number Original line Diff line number Diff line
@@ -1055,26 +1055,28 @@ static int mdss_dp_wait4video_ready(struct mdss_dp_drv_pdata *dp_drv)
static void mdss_dp_update_cable_status(struct mdss_dp_drv_pdata *dp,
static void mdss_dp_update_cable_status(struct mdss_dp_drv_pdata *dp,
		bool connected)
		bool connected)
{
{
	mutex_lock(&dp->pd_msg_mutex);
	mutex_lock(&dp->attention_lock);
	pr_debug("cable_connected to %d\n", connected);
	pr_debug("cable_connected to %d\n", connected);
	if (dp->cable_connected != connected)
	if (dp->cable_connected != connected)
		dp->cable_connected = connected;
		dp->cable_connected = connected;
	else
	else
		pr_debug("no change in cable status\n");
		pr_debug("no change in cable status\n");
	mutex_unlock(&dp->pd_msg_mutex);
	mutex_unlock(&dp->attention_lock);
}
}


static int dp_get_cable_status(struct platform_device *pdev, u32 vote)
static int dp_get_cable_status(struct platform_device *pdev, u32 vote)
{
{
	struct mdss_dp_drv_pdata *dp_ctrl = platform_get_drvdata(pdev);
	struct mdss_dp_drv_pdata *dp = platform_get_drvdata(pdev);
	u32 hpd;
	u32 hpd;


	if (!dp_ctrl) {
	if (!dp) {
		DEV_ERR("%s: invalid input\n", __func__);
		DEV_ERR("%s: invalid input\n", __func__);
		return -ENODEV;
		return -ENODEV;
	}
	}


	hpd = dp_ctrl->cable_connected;
	mutex_lock(&dp->attention_lock);
	hpd = dp->cable_connected;
	mutex_unlock(&dp->attention_lock);


	return hpd;
	return hpd;
}
}
@@ -2043,7 +2045,6 @@ static int mdss_dp_notify_clients(struct mdss_dp_drv_pdata *dp,
	bool notify = false;
	bool notify = false;
	bool connect;
	bool connect;


	mutex_lock(&dp->pd_msg_mutex);
	pr_debug("beginning notification\n");
	pr_debug("beginning notification\n");
	if (status == dp->hpd_notification_status) {
	if (status == dp->hpd_notification_status) {
		pr_debug("No change in status %s --> %s\n",
		pr_debug("No change in status %s --> %s\n",
@@ -2135,7 +2136,6 @@ notify:


end:
end:
	dp->hpd_notification_status = status;
	dp->hpd_notification_status = status;
	mutex_unlock(&dp->pd_msg_mutex);
	return ret;
	return ret;
}
}


@@ -2423,12 +2423,16 @@ static ssize_t mdss_dp_rda_connected(struct device *dev,
{
{
	ssize_t ret;
	ssize_t ret;
	struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
	struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
	bool cable_connected;


	if (!dp)
	if (!dp)
		return -EINVAL;
		return -EINVAL;


	ret = snprintf(buf, PAGE_SIZE, "%d\n", dp->cable_connected);
	mutex_lock(&dp->attention_lock);
	pr_debug("%d\n", dp->cable_connected);
	cable_connected = dp->cable_connected;
	mutex_unlock(&dp->attention_lock);
	ret = snprintf(buf, PAGE_SIZE, "%d\n", cable_connected);
	pr_debug("%d\n", cable_connected);


	return ret;
	return ret;
}
}
@@ -2597,6 +2601,7 @@ static ssize_t mdss_dp_wta_hpd(struct device *dev,
	int hpd, rc;
	int hpd, rc;
	ssize_t ret = strnlen(buf, PAGE_SIZE);
	ssize_t ret = strnlen(buf, PAGE_SIZE);
	struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
	struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
	bool cable_connected;


	if (!dp) {
	if (!dp) {
		pr_err("invalid data\n");
		pr_err("invalid data\n");
@@ -2612,9 +2617,13 @@ static ssize_t mdss_dp_wta_hpd(struct device *dev,
	}
	}


	dp->hpd = !!hpd;
	dp->hpd = !!hpd;
	pr_debug("hpd=%d\n", dp->hpd);
	mutex_lock(&dp->attention_lock);
	cable_connected = dp->cable_connected;
	mutex_unlock(&dp->attention_lock);
	pr_debug("hpd=%d cable_connected=%s\n", dp->hpd,
		cable_connected ? "true" : "false");


	if (dp->hpd && dp->cable_connected) {
	if (dp->hpd && cable_connected) {
		if (dp->alt_mode.current_state & DP_CONFIGURE_DONE) {
		if (dp->alt_mode.current_state & DP_CONFIGURE_DONE) {
			mdss_dp_host_init(&dp->panel_data);
			mdss_dp_host_init(&dp->panel_data);
			mdss_dp_process_hpd_high(dp);
			mdss_dp_process_hpd_high(dp);
@@ -3248,10 +3257,21 @@ static int mdss_dp_event_thread(void *data)


	ev_data = (struct mdss_dp_event_data *)data;
	ev_data = (struct mdss_dp_event_data *)data;


	pr_debug("starting\n");
	while (!kthread_should_stop()) {
	while (!kthread_should_stop()) {
		wait_event(ev_data->event_q,
		wait_event(ev_data->event_q,
			(ev_data->pndx != ev_data->gndx) ||
			(ev_data->pndx != ev_data->gndx) ||
			kthread_should_stop());
			kthread_should_stop() ||
			kthread_should_park());
		if (kthread_should_stop())
			return 0;

		if (kthread_should_park()) {
			pr_debug("parking event thread\n");
			kthread_parkme();
			continue;
		}

		spin_lock_irqsave(&ev_data->event_lock, flag);
		spin_lock_irqsave(&ev_data->event_lock, flag);
		ev = &(ev_data->event_list[ev_data->gndx++]);
		ev = &(ev_data->event_list[ev_data->gndx++]);
		todo = ev->id;
		todo = ev->id;
@@ -3427,6 +3447,27 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp)
	return 0;
	return 0;
}
}


static void mdss_dp_reset_event_list(struct mdss_dp_drv_pdata *dp)
{
	struct mdss_dp_event_data *ev_data = &dp->dp_event;

	spin_lock(&ev_data->event_lock);
	ev_data->pndx = ev_data->gndx = 0;
	spin_unlock(&ev_data->event_lock);

	mutex_lock(&dp->attention_lock);
	INIT_LIST_HEAD(&dp->attention_head);
	mutex_unlock(&dp->attention_lock);
}

static void mdss_dp_reset_sw_state(struct mdss_dp_drv_pdata *dp)
{
	pr_debug("enter\n");
	mdss_dp_reset_event_list(dp);
	atomic_set(&dp->notification_pending, 0);
	complete_all(&dp->notification_comp);
}

static void usbpd_connect_callback(struct usbpd_svid_handler *hdlr)
static void usbpd_connect_callback(struct usbpd_svid_handler *hdlr)
{
{
	struct mdss_dp_drv_pdata *dp_drv;
	struct mdss_dp_drv_pdata *dp_drv;
@@ -3438,6 +3479,8 @@ static void usbpd_connect_callback(struct usbpd_svid_handler *hdlr)
	}
	}


	mdss_dp_update_cable_status(dp_drv, true);
	mdss_dp_update_cable_status(dp_drv, true);
	if (dp_drv->ev_thread)
		kthread_unpark(dp_drv->ev_thread);


	if (dp_drv->hpd)
	if (dp_drv->hpd)
		dp_send_events(dp_drv, EV_USBPD_DISCOVER_MODES);
		dp_send_events(dp_drv, EV_USBPD_DISCOVER_MODES);
@@ -3457,6 +3500,9 @@ static void usbpd_disconnect_callback(struct usbpd_svid_handler *hdlr)
	mdss_dp_update_cable_status(dp_drv, false);
	mdss_dp_update_cable_status(dp_drv, false);
	dp_drv->alt_mode.current_state = UNKNOWN_STATE;
	dp_drv->alt_mode.current_state = UNKNOWN_STATE;


	mdss_dp_reset_sw_state(dp_drv);
	kthread_park(dp_drv->ev_thread);

	/**
	/**
	 * Manually turn off the DP controller if we are in PHY
	 * Manually turn off the DP controller if we are in PHY
	 * testing mode.
	 * testing mode.
@@ -3975,6 +4021,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
		node->vdo = *vdos;
		node->vdo = *vdos;


		mutex_lock(&dp_drv->attention_lock);
		mutex_lock(&dp_drv->attention_lock);
		if (dp_drv->cable_connected)
			list_add_tail(&node->list, &dp_drv->attention_head);
			list_add_tail(&node->list, &dp_drv->attention_head);
		mutex_unlock(&dp_drv->attention_lock);
		mutex_unlock(&dp_drv->attention_lock);


@@ -4093,6 +4140,11 @@ static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp)


		reinit_completion(&dp->notification_comp);
		reinit_completion(&dp->notification_comp);
		mutex_lock(&dp->attention_lock);
		mutex_lock(&dp->attention_lock);
		if (!dp->cable_connected) {
			pr_debug("cable disconnected, returning\n");
			mutex_unlock(&dp->attention_lock);
			goto exit;
		}
		node = list_first_entry(&dp->attention_head,
		node = list_first_entry(&dp->attention_head,
				struct mdss_dp_attention_node, list);
				struct mdss_dp_attention_node, list);


@@ -4124,6 +4176,7 @@ static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp)
		pr_debug("done processing item %d in the list\n", i);
		pr_debug("done processing item %d in the list\n", i);
	};
	};


exit:
	pr_debug("exit\n");
	pr_debug("exit\n");
}
}


@@ -4199,7 +4252,6 @@ static int mdss_dp_probe(struct platform_device *pdev)
	dp_drv->mask1 = EDP_INTR_MASK1;
	dp_drv->mask1 = EDP_INTR_MASK1;
	dp_drv->mask2 = EDP_INTR_MASK2;
	dp_drv->mask2 = EDP_INTR_MASK2;
	mutex_init(&dp_drv->emutex);
	mutex_init(&dp_drv->emutex);
	mutex_init(&dp_drv->pd_msg_mutex);
	mutex_init(&dp_drv->attention_lock);
	mutex_init(&dp_drv->attention_lock);
	mutex_init(&dp_drv->hdcp_mutex);
	mutex_init(&dp_drv->hdcp_mutex);
	spin_lock_init(&dp_drv->lock);
	spin_lock_init(&dp_drv->lock);
+0 −1
Original line number Original line Diff line number Diff line
@@ -617,7 +617,6 @@ struct mdss_dp_drv_pdata {
	struct completion notification_comp;
	struct completion notification_comp;
	struct mutex aux_mutex;
	struct mutex aux_mutex;
	struct mutex train_mutex;
	struct mutex train_mutex;
	struct mutex pd_msg_mutex;
	struct mutex attention_lock;
	struct mutex attention_lock;
	struct mutex hdcp_mutex;
	struct mutex hdcp_mutex;
	bool cable_connected;
	bool cable_connected;