summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2017-10-05 12:51:26 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-12-07 22:38:23 -0800
commite5f8604fdbb137f26a6cdb89b33b4214ead43dfc (patch)
treebebbbef8313be9b5f33c175d2413279b82d9203d /drivers/usb
parent7099c46a662042dc275bcaaa90750d11a2d89ac3 (diff)
usb: pd: Send pending VDM message upon entering SNK/SRC_Ready
Entering SNK_Ready or SRC_Ready state from usbpd_set_state() is somewhat terminal as it is the end state of a contract negotiation. If there was a previous pending VDM message waiting to be sent, for example the start of a Discovery which was queued prior to a PR Swap, it would not get sent. Check for this and enqueue usbpd_sm once again so that it could be sent out. Otherwise, start the Discovery process in case we are in DFP mode, and do that for SNK_Ready as well. Change-Id: I4516ccb0deec8cdabdb62d539d7d2b66dc23f1ee Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/pd/policy_engine.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 3c0386ee5875..06e0ef9a37d7 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1140,14 +1140,13 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SRC_READY:
pd->in_explicit_contract = true;
- if (pd->current_dr == DR_DFP) {
- /* don't start USB host until after SVDM discovery */
- if (pd->vdm_state == VDM_NONE)
- usbpd_send_svdm(pd, USBPD_SID,
- USBPD_SVDM_DISCOVER_IDENTITY,
- SVDM_CMD_TYPE_INITIATOR, 0,
- NULL, 0);
- }
+
+ if (pd->vdm_tx)
+ kick_sm(pd, 0);
+ else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
+ usbpd_send_svdm(pd, USBPD_SID,
+ USBPD_SVDM_DISCOVER_IDENTITY,
+ SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
complete(&pd->is_ready);
@@ -1282,6 +1281,14 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SNK_READY:
pd->in_explicit_contract = true;
+
+ if (pd->vdm_tx)
+ kick_sm(pd, 0);
+ else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
+ usbpd_send_svdm(pd, USBPD_SID,
+ USBPD_SVDM_DISCOVER_IDENTITY,
+ SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
+
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
complete(&pd->is_ready);
dual_role_instance_changed(pd->dual_role);