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

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

Merge "dwc3: Handle USB spoof disconnect when EUD is enabled"

parents 688bf453 e86c77ed
Loading
Loading
Loading
Loading
+53 −7
Original line number Diff line number Diff line
@@ -444,7 +444,9 @@ struct dwc3_msm {
	bool			in_device_mode;
	enum usb_device_speed	max_rh_port_speed;
	unsigned int		tx_fifo_size;
	bool			check_eud_state;
	bool			vbus_active;
	bool			eud_active;
	bool			suspend;
	bool			use_pdc_interrupts;
	enum dwc3_id_state	id_state;
@@ -3149,6 +3151,39 @@ static void dwc3_ext_event_notify(struct dwc3_msm *mdwc)
		clear_bit(B_SUSPEND, &mdwc->inputs);
	}

	if (mdwc->check_eud_state) {
		mdwc->hs_phy->flags &=
			~(EUD_SPOOF_CONNECT | EUD_SPOOF_DISCONNECT);
		dev_dbg(mdwc->dev, "eud: state:%d active:%d hs_phy_flags:0x%x\n",
			mdwc->check_eud_state, mdwc->eud_active,
			mdwc->hs_phy->flags);
		if (mdwc->eud_active) {
			mdwc->hs_phy->flags |= EUD_SPOOF_CONNECT;
			dev_dbg(mdwc->dev, "EUD: XCVR: BSV set\n");
			set_bit(B_SESS_VLD, &mdwc->inputs);
		} else {
			mdwc->hs_phy->flags |= EUD_SPOOF_DISCONNECT;
			dev_dbg(mdwc->dev, "EUD: XCVR: BSV clear\n");
			clear_bit(B_SESS_VLD, &mdwc->inputs);
		}

		mdwc->check_eud_state = false;
	}


	dev_dbg(mdwc->dev, "eud: state:%d active:%d hs_phy_flags:0x%x\n",
		mdwc->check_eud_state, mdwc->eud_active, mdwc->hs_phy->flags);

	/* handle case of USB cable disconnect after USB spoof disconnect */
	if (!mdwc->vbus_active &&
			(mdwc->hs_phy->flags & EUD_SPOOF_DISCONNECT)) {
		mdwc->hs_phy->flags &= ~EUD_SPOOF_DISCONNECT;
		mdwc->hs_phy->flags |= PHY_SUS_OVERRIDE;
		usb_phy_set_suspend(mdwc->hs_phy, 1);
		mdwc->hs_phy->flags &= ~PHY_SUS_OVERRIDE;
		return;
	}

	queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0);
}

@@ -3475,6 +3510,8 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
	struct extcon_dev *edev = ptr;
	struct extcon_nb *enb = container_of(nb, struct extcon_nb, vbus_nb);
	struct dwc3_msm *mdwc = enb->mdwc;
	char *eud_str;
	const char *edev_name;

	if (!edev || !mdwc)
		return NOTIFY_DONE;
@@ -3482,15 +3519,24 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
	dwc = platform_get_drvdata(mdwc->dwc3);

	dbg_event(0xFF, "extcon idx", enb->idx);
	dev_dbg(mdwc->dev, "vbus:%ld event received\n", event);
	edev_name = extcon_get_edev_name(edev);
	dbg_log_string("edev:%s\n", edev_name);

	/* detect USB spoof disconnect/connect notification with EUD device */
	eud_str = strnstr(edev_name, "eud", strlen(edev_name));
	if (eud_str) {
		if (mdwc->eud_active == event)
			return NOTIFY_DONE;
		mdwc->eud_active = event;
		mdwc->check_eud_state = true;
	} else {
		if (mdwc->vbus_active == event)
			return NOTIFY_DONE;
		mdwc->vbus_active = event;
	}

	mdwc->ext_idx = enb->idx;

	dev_dbg(mdwc->dev, "vbus:%ld event received\n", event);

	mdwc->vbus_active = event;
	if (dwc->dr_mode == USB_DR_MODE_OTG && !mdwc->in_restart)
		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);

+13 −4
Original line number Diff line number Diff line
@@ -341,7 +341,8 @@ static int msm_hsphy_init(struct usb_phy *uphy)

	if (phy->eud_enable_reg && readl_relaxed(phy->eud_enable_reg)) {
		dev_err(phy->phy.dev, "eud is enabled\n");
		return 0;
		ret = msm_hsphy_enable_power(phy, true);
		return ret;
	}

	ret = msm_hsphy_enable_power(phy, true);
@@ -460,11 +461,15 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
	struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);

	if (phy->suspended && suspend) {
		if (phy->phy.flags & PHY_SUS_OVERRIDE)
			goto suspend;

		dev_dbg(uphy->dev, "%s: USB PHY is already suspended\n",
								__func__);
		return 0;
	}

suspend:
	if (suspend) { /* Bus suspend */
		if (phy->cable_connected ||
			(phy->phy.flags & PHY_HOST_MODE)) {
@@ -480,9 +485,13 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
			msm_hsphy_enable_clocks(phy, false);
		} else {/* Cable disconnect */
			mutex_lock(&phy->phy_lock);
			dev_dbg(uphy->dev, "phy->flags:0x%x\n", phy->phy.flags);
			if (!phy->dpdm_enable) {
				if (!(phy->phy.flags & EUD_SPOOF_DISCONNECT)) {
					dev_dbg(uphy->dev, "turning off clocks/ldo\n");
					msm_hsphy_enable_clocks(phy, false);
					msm_hsphy_enable_power(phy, false);
				}
			} else {
				dev_dbg(uphy->dev, "dpdm reg still active.  Keep clocks/ldo ON\n");
			}
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@
#define PHY_LANE_B			BIT(3)
#define PHY_HSFS_MODE			BIT(4)
#define PHY_LS_MODE			BIT(5)
#define EUD_SPOOF_DISCONNECT		BIT(6)
#define EUD_SPOOF_CONNECT		BIT(7)
#define PHY_SUS_OVERRIDE		BIT(8)

/*
 * The following are bit fields describing the USB BAM options.