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

Commit 34fbda74 authored by Chandana Kishori Chiluveru's avatar Chandana Kishori Chiluveru
Browse files

usb: pd: Add timeout for mode change



Currently USB driver tries to set power role as none in mode
change and waits for disconnect followed by connect notifications
to set new mode. But there is a chance that it might fail if other
device is not dual-role capable.

When device connected to window host pc and try data role swap.
Device trying to change the mode and setting the power role none.
But host PC does not support this and device never switching back
to original role and device enumeration does not happening with
host pc connected.

Fix it by having timeouts in mode setting. Setting it to dual-role and
bail out in case of timeout happens.

Change-Id: Iaac671f46070f756243b93a27ab99ddbbdff8ffa
Signed-off-by: default avatarChandana Kishori Chiluveru <cchiluve@codeaurora.org>
parent 409af4b4
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -3550,6 +3550,8 @@ static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
		enum dual_role_property prop, const unsigned int *val)
{
	struct usbpd *pd = dual_role_get_drvdata(dual_role);
	union power_supply_propval value;
	int wait_count = 5;
	bool do_swap = false;

	if (!pd)
@@ -3572,9 +3574,33 @@ static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
		set_power_role(pd, PR_NONE);

		/* wait until it takes effect */
		while (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE)
		while (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE &&
				--wait_count)
			msleep(20);

		if (!wait_count) {
			usbpd_err(&pd->dev, "setting mode timed out\n");
			/* Setting it to DRP. HW can figure out new mode */
			value.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
			power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &value);
			return -ETIMEDOUT;
		}

		/* if we cannot have a valid connection, fallback to old role */
		wait_count = 5;
		while (pd->current_pr == PR_NONE && --wait_count)
			msleep(300);

		if (!wait_count) {
			usbpd_err(&pd->dev, "setting mode timed out\n");
			/* Setting it to DRP. HW can figure out new mode */
			value.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
			power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &value);
			return -ETIMEDOUT;
		}

		break;

	case DUAL_ROLE_PROP_DR: