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

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

Merge "usb: pd: ensure source hard reset is handled timely"

parents 957ea698 4b323288
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -368,6 +368,7 @@ struct usbpd {

	enum usbpd_state	current_state;
	bool			hard_reset_recvd;
	ktime_t			hard_reset_recvd_time;
	struct list_head	rx_q;
	spinlock_t		rx_lock;
	struct rx_msg		*rx_ext_msg;
@@ -614,6 +615,9 @@ static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data,
	int ret;
	u16 hdr;

	if (pd->hard_reset_recvd)
		return -EBUSY;

	hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
			pd->tx_msgid, num_data, pd->spec_rev);

@@ -805,11 +809,13 @@ static void phy_sig_received(struct usbpd *pd, enum pd_sig_type sig)
		return;
	}

	usbpd_dbg(&pd->dev, "hard reset received\n");
	pd->hard_reset_recvd = true;
	pd->hard_reset_recvd_time = ktime_get();

	usbpd_err(&pd->dev, "hard reset received\n");

	/* Force CC logic to source/sink to keep Rp/Rd unchanged */
	set_power_role(pd, pd->current_pr);
	pd->hard_reset_recvd = true;
	power_supply_set_property(pd->usb_psy,
			POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);

@@ -1074,6 +1080,9 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
	unsigned long flags;
	int ret;

	if (pd->hard_reset_recvd) /* let usbpd_sm handle it */
		return;

	usbpd_dbg(&pd->dev, "%s -> %s\n",
			usbpd_state_strings[pd->current_state],
			usbpd_state_strings[next_state]);
@@ -2044,8 +2053,13 @@ static void usbpd_sm(struct work_struct *w)
		if (pd->current_pr == PR_SINK) {
			usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
		} else {
			s64 delta = ktime_ms_delta(ktime_get(),
					pd->hard_reset_recvd_time);
			pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
			kick_sm(pd, PS_HARD_RESET_TIME);
			if (delta >= PS_HARD_RESET_TIME)
				kick_sm(pd, 0);
			else
				kick_sm(pd, PS_HARD_RESET_TIME - (int)delta);
		}

		goto sm_done;
+8 −0
Original line number Diff line number Diff line
@@ -582,6 +582,10 @@ static irqreturn_t pdphy_msg_tx_irq(int irq, void *data)
{
	struct usb_pdphy *pdphy = data;

	/* TX already aborted by received signal */
	if (pdphy->tx_status != -EINPROGRESS)
		return IRQ_HANDLED;

	if (irq == pdphy->msg_tx_irq) {
		pdphy->msg_tx_cnt++;
		pdphy->tx_status = 0;
@@ -635,6 +639,10 @@ static irqreturn_t pdphy_sig_rx_irq_thread(int irq, void *data)
	if (pdphy->signal_cb)
		pdphy->signal_cb(pdphy->usbpd, frame_type);

	if (pdphy->tx_status == -EINPROGRESS) {
		pdphy->tx_status = -EBUSY;
		wake_up(&pdphy->tx_waitq);
	}
done:
	return IRQ_HANDLED;
}