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

Commit 8fc73b9b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: pd: Add support for enabling PD2.0 only as source"

parents 958a76c8 917f4c3e
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -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,8 @@ struct usbpd {
	bool			peer_usb_comm;
	bool			peer_pr_swap;
	bool			peer_dr_swap;
	bool			no_usb3dp_concurrency;
	bool			pd20_source_only;

	u32			sink_caps[7];
	int			num_sink_caps;
@@ -610,6 +613,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.
@@ -1565,6 +1588,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 */
@@ -2107,6 +2131,10 @@ static int usbpd_startup_common(struct usbpd *pd,
		 * support up to PD 3.0; if peer is 2.0
		 * phy_msg_received() will handle the downgrade.
		 */
		if ((pd->pd20_source_only) &&
			pd->current_state == PE_SRC_STARTUP)
			pd->spec_rev = USBPD_REV_20;
		else
			pd->spec_rev = USBPD_REV_30;

		if (pd->pd_phy_opened) {
@@ -2235,6 +2263,9 @@ static void handle_state_src_startup_wait_for_vdm_resp(struct usbpd *pd,
	 * Emarker may have negotiated down to rev 2.0.
	 * Reset to 3.0 to begin SOP communication with sink
	 */
	if (pd->pd20_source_only)
		pd->spec_rev = USBPD_REV_20;
	else
		pd->spec_rev = USBPD_REV_30;

	pd->current_state = PE_SRC_SEND_CAPABILITIES;
@@ -4697,6 +4728,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);
@@ -4752,6 +4784,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) {
@@ -4790,6 +4825,9 @@ struct usbpd *usbpd_create(struct device *parent)
		pd->num_sink_caps = ARRAY_SIZE(default_snk_caps);
	}

	if (device_property_read_bool(parent, "qcom,pd-20-source-only"))
		pd->pd20_source_only = true;

	/*
	 * Register a Type-C class instance (/sys/class/typec/portX).
	 * Note this is different than the /sys/class/usbpd/ created above.