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

Commit 91eff369 authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Gerrit - the friendly Code Review server
Browse files

USB: pd: Restart host mode in high speed if no usb3 & dp concurrency



It is required to restart usb host mode in high speed on platforms not
supporting usb3 ss and DP concurrency. Hence add required support to
restart host mode in high speed for those platforms, when dp is
detected through discovery of svids.

Change-Id: I1bbd9679b9354828d751ed74ef5d99cb8541e698
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: default avatarChetan C R <cchinnad@codeaurora.org>
parent 754822b0
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/completion.h>
@@ -381,6 +381,7 @@ struct usbpd {
	struct workqueue_struct	*wq;
	struct work_struct	sm_work;
	struct work_struct	start_periph_work;
	struct work_struct	restart_host_work;
	struct hrtimer		timer;
	bool			sm_queued;

@@ -406,6 +407,7 @@ struct usbpd {
	bool			peer_usb_comm;
	bool			peer_pr_swap;
	bool			peer_dr_swap;
	bool			no_usb3dp_concurrency;

	u32			sink_caps[7];
	int			num_sink_caps;
@@ -609,6 +611,26 @@ static void start_usb_peripheral_work(struct work_struct *w)
	}
}

static void restart_usb_host_work(struct work_struct *w)
{
	struct usbpd *pd = container_of(w, struct usbpd, restart_host_work);
	int ret;

	if (!pd->no_usb3dp_concurrency)
		return;

	stop_usb_host(pd);

	/* blocks until USB host is completely stopped */
	ret = extcon_blocking_sync(pd->extcon, EXTCON_USB_HOST, STOP_USB_HOST);
	if (ret) {
		usbpd_err(&pd->dev, "err(%d) stopping host", ret);
		return;
	}

	start_usb_host(pd, false);
}

/**
 * This API allows client driver to request for releasing SS lanes. It should
 * not be called from atomic context.
@@ -1564,6 +1586,7 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)

		/* Set to USB and DP cocurrency mode */
		extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 2);
		queue_work(pd->wq, &pd->restart_host_work);
	}

	/* if it's a supported SVID, pass the message to the handler */
@@ -4678,6 +4701,7 @@ struct usbpd *usbpd_create(struct device *parent)
	}
	INIT_WORK(&pd->sm_work, usbpd_sm);
	INIT_WORK(&pd->start_periph_work, start_usb_peripheral_work);
	INIT_WORK(&pd->restart_host_work, restart_usb_host_work);
	hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	pd->timer.function = pd_timeout;
	mutex_init(&pd->swap_lock);
@@ -4733,6 +4757,9 @@ struct usbpd *usbpd_create(struct device *parent)
	extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
			EXTCON_PROP_USB_SS);

	if (device_property_read_bool(parent, "qcom,no-usb3-dp-concurrency"))
		pd->no_usb3dp_concurrency = true;

	pd->num_sink_caps = device_property_read_u32_array(parent,
			"qcom,default-sink-caps", NULL, 0);
	if (pd->num_sink_caps > 0) {