mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Merge "dwc3: Handle USB spoof disconnect when EUD is enabled"
This commit is contained in:
commit
651126b74a
3 changed files with 69 additions and 11 deletions
|
|
@ -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);
|
||||
|
||||
if (mdwc->vbus_active == event)
|
||||
return NOTIFY_DONE;
|
||||
/* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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__);
|
||||
__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) {
|
||||
msm_hsphy_enable_clocks(phy, false);
|
||||
msm_hsphy_enable_power(phy, false);
|
||||
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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue