summaryrefslogtreecommitdiff
path: root/drivers/usb/pd
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2016-07-12 17:39:12 -0700
committerJack Pham <jackp@codeaurora.org>2016-08-16 16:26:21 -0700
commit0c924e6706a9a1fbf1d363effb6e3613ca0649f6 (patch)
tree9816a658502fcf7c65362ddd87ce039acca6fd25 /drivers/usb/pd
parenta8967b290f0436355eedd711c2a35d8b7f67caba (diff)
usb: pd: Fix ERROR_RECOVERY handling
When entering ERROR_RECOVERY, the forced disconnect should be processed first by queuing the work function to handle it in the usual way. The required minimum delay should then be done after this, before restoring the port to dual-role, and thereby re-establishing the source/sink connection. Change-Id: I672cdb59277af103045236232e54dc24f9f7fb01 Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'drivers/usb/pd')
-rw-r--r--drivers/usb/pd/policy_engine.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 0cc57e41ebb1..b011efe189e7 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -575,8 +575,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_ERROR_RECOVERY: /* perform hard disconnect/reconnect */
pd->in_pr_swap = false;
set_power_role(pd, PR_NONE);
- hrtimer_start(&pd->timer, ms_to_ktime(ERROR_RECOVERY_TIME),
- HRTIMER_MODE_REL);
+ pd->typec_mode = POWER_SUPPLY_TYPEC_NONE;
+ queue_work(pd->wq, &pd->sm_work);
break;
/* Source states */
@@ -1271,12 +1271,18 @@ static void usbpd_sm(struct work_struct *w)
reset_vdm_state(pd);
+ if (pd->current_state == PE_ERROR_RECOVERY)
+ /* forced disconnect, wait before resetting to DRP */
+ usleep_range(ERROR_RECOVERY_TIME * USEC_PER_MSEC,
+ (ERROR_RECOVERY_TIME + 5) * USEC_PER_MSEC);
+
/* Set CC back to DRP toggle */
val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
power_supply_set_property(pd->usb_psy,
POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
pd->current_state = PE_UNKNOWN;
+
return;
}