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

Commit 1b6a0c7f authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: pd: Allow receiving VDM messages during suspend"

parents 79b9f885 1322981d
Loading
Loading
Loading
Loading
+34 −6
Original line number Diff line number Diff line
@@ -457,6 +457,7 @@ struct usbpd {
	struct mutex		svid_handler_lock;
	struct list_head	svid_handlers;
	ktime_t			svdm_start_time;
	bool			vdm_in_suspend;

	struct list_head	instance;

@@ -659,15 +660,21 @@ static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid)
{
	struct usbpd_svid_handler *handler;

	/* in_interrupt() == true when handling VDM RX during suspend */
	if (!in_interrupt())
		mutex_lock(&pd->svid_handler_lock);

	list_for_each_entry(handler, &pd->svid_handlers, entry) {
		if (svid == handler->svid) {
			if (!in_interrupt())
				mutex_unlock(&pd->svid_handler_lock);
			return handler;
		}
	}

	if (!in_interrupt())
		mutex_unlock(&pd->svid_handler_lock);

	return NULL;
}

@@ -1074,6 +1081,8 @@ static struct rx_msg *pd_ext_msg_received(struct usbpd *pd, u16 header, u8 *buf,
	return rx_msg;	/* queue it for usbpd_sm */
}

static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg);

static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop,
		u8 *buf, size_t len)
{
@@ -1146,6 +1155,13 @@ static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop,
			return;
	}

	if (pd->vdm_in_suspend && msg_type == MSG_VDM) {
		usbpd_dbg(&pd->dev, "Skip wq and handle VDM directly\n");
		handle_vdm_rx(pd, rx_msg);
		kfree(rx_msg);
		return;
	}

	spin_lock_irqsave(&pd->rx_lock, flags);
	list_add_tail(&rx_msg->entry, &pd->rx_q);
	spin_unlock_irqrestore(&pd->rx_lock, flags);
@@ -1324,6 +1340,7 @@ int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos)

	/* VDM will get sent in PE_SRC/SNK_READY state handling */
	pd->vdm_tx = vdm_tx;
	pd->vdm_in_suspend = false;

	/* slight delay before queuing to prioritize handling of incoming VDM */
	if (pd->in_explicit_contract)
@@ -1346,6 +1363,14 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
}
EXPORT_SYMBOL(usbpd_send_svdm);

void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend)
{
	usbpd_dbg(&pd->dev, "VDM in_suspend:%d\n", in_suspend);

	pd->vdm_in_suspend = in_suspend;
}
EXPORT_SYMBOL(usbpd_vdm_in_suspend);

static void handle_vdm_resp_ack(struct usbpd *pd, u32 *vdos, u8 num_vdos,
	u16 vdm_hdr)
{
@@ -1529,6 +1554,10 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
		return;
	}

	if (cmd_type != SVDM_CMD_TYPE_INITIATOR &&
			pd->current_state != PE_SRC_STARTUP_WAIT_FOR_VDM_RESP)
		start_src_ams(pd, false);

	if (handler && handler->svdm_received) {
		handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos);

@@ -1685,6 +1714,7 @@ static void reset_vdm_state(struct usbpd *pd)
	kfree(pd->vdm_tx);
	pd->vdm_tx = NULL;
	pd->ss_lane_svid = 0x0;
	pd->vdm_in_suspend = false;
}

static void handle_get_src_cap_extended(struct usbpd *pd)
@@ -2300,7 +2330,7 @@ static void enter_state_src_ready(struct usbpd *pd)

	pd->in_explicit_contract = true;

	if (pd->vdm_tx)
	if (pd->vdm_tx && !pd->sm_queued)
		kick_sm(pd, 0);
	else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
		usbpd_send_svdm(pd, USBPD_SID,
@@ -2361,8 +2391,6 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg)
		}

		vconn_swap(pd);
		if (!pd->vdm_tx)
			start_src_ams(pd, false);
	} else if (IS_DATA(rx_msg, MSG_VDM)) {
		handle_vdm_rx(pd, rx_msg);
	} else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP_EXTENDED)) {
+4 −0
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
 *         otherwise ORIENTATION_NONE if not attached
 */
enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd);

void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend);
#else
static inline struct usbpd *devm_usbpd_get_by_phandle(struct device *dev,
		const char *phandle)
@@ -134,6 +136,8 @@ static inline enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
{
	return ORIENTATION_NONE;
}

static inline void usbpd_vdm_in_suspend(struct usbpd *pd, bool in_suspend) { }
#endif /* IS_ENABLED(CONFIG_USB_PD_POLICY) */

/*