From: Badhri Jagan Sridharan <badhri@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Guenter Roeck <linux@roeck-us.net>
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
Badhri Jagan Sridharan <Badhri@google.com>
Subject: [PATCH 03/11 v3] staging: typec: tcpm: Prevent TCPM from looping in SRC_TRYWAIT
Date: Mon, 28 Aug 2017 10:23:14 -0700 [thread overview]
Message-ID: <20170828172322.7166-3-Badhri@google.com> (raw)
In-Reply-To: <20170828172322.7166-1-Badhri@google.com>
According to the spec the following is the condition
for exiting TryWait.SRC:
"The port shall transition to Attached.SRC when V BUS is at vSafe0V
and the SRC.Rd state is detected on exactly one of the CC pins for at
least tCCDebounce. The port shall transition to Unattached.SNK after
tDRPTry if neither of the CC1 or CC2 pins are in the SRC.Rd state"
TCPM at present keeps re-entering the SRC_TRYWAIT and keeps restarting
tDRPTry if the CC presents Rp and disconnects within tCCDebounce.
For example:
[ 447.164308] pending state change SRC_TRYWAIT -> SRC_ATTACHED @ 200 ms
[ 447.164386] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, disconnected]
[ 447.164406] state change SRC_TRYWAIT -> SRC_TRYWAIT
[ 447.164573] cc:=3
[ 447.191408] pending state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED @ 100 ms
[ 447.191478] CC1: 0 -> 0, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, disconnected]
[ 447.207261] CC1: 0 -> 2, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, connected]
[ 447.207306] state change SRC_TRYWAIT -> SRC_TRYWAIT
[ 447.207485] cc:=3
[ 447.237283] pending state change SRC_TRYWAIT -> SRC_ATTACHED @ 200 ms
[ 447.237357] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, disconnected]
[ 447.237379] state change SRC_TRYWAIT -> SRC_TRYWAIT
[ 447.237532] cc:=3
[ 447.263219] pending state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED @ 100 ms
[ 447.263289] CC1: 0 -> 0, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, disconnected]
[ 447.280926] CC1: 0 -> 2, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, connected]
[ 447.280970] state change SRC_TRYWAIT -> SRC_TRYWAIT
[ 447.281158] cc:=3
[ 447.307767] pending state change SRC_TRYWAIT -> SRC_ATTACHED @ 200 ms
[ 447.307838] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_TRYWAIT, polarity 0, disconnected]
[ 447.307858] state change SRC_TRYWAIT -> SRC_TRYWAIT
In TCPM, tDRPTry is set tp 100ms (min 75ms and max 150ms)
and tCCdebounce is set to 200ms (min 100ms and max 200ms).
To overcome the issue, record the time at which the port
enters TryWait.SRC(SRC_TRYWAIT) and re-enter SRC_TRYWAIT
only when CC keeps debouncing within tDRPTry.
Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
---
Changelog since v1:
- Corrected tag
Changelog since v2:
- added Reviewed-by: Guenter Roeck <linux@roeck-us.net>
- fixed version/sequence numbers
drivers/staging/typec/tcpm.c | 45 ++++++++++++++++++++++++++++----------------
1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c
index 1219e3bc13ef..d45ffa8f2cfd 100644
--- a/drivers/staging/typec/tcpm.c
+++ b/drivers/staging/typec/tcpm.c
@@ -17,6 +17,7 @@
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -105,6 +106,7 @@
S(SNK_TRY), \
S(SNK_TRY_WAIT), \
S(SRC_TRYWAIT), \
+ S(SRC_TRYWAIT_DEBOUNCE), \
S(SRC_TRYWAIT_UNATTACHED), \
\
S(SRC_TRY), \
@@ -284,6 +286,9 @@ struct tcpm_port {
struct typec_altmode *partner_altmode[SVID_DISCOVERY_MAX];
struct typec_altmode *port_altmode[SVID_DISCOVERY_MAX];
+ /* Deadline in jiffies to exit src_try_wait state */
+ unsigned long max_wait;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
struct mutex logbuffer_lock; /* log buffer access lock */
@@ -2204,6 +2209,7 @@ static void run_state_machine(struct tcpm_port *port)
if (!tcpm_port_is_sink(port)) {
tcpm_set_state(port, SRC_TRYWAIT,
PD_T_PD_DEBOUNCE);
+ port->max_wait = 0;
break;
}
/* No vbus, cc state is sink or open */
@@ -2211,11 +2217,22 @@ static void run_state_machine(struct tcpm_port *port)
break;
case SRC_TRYWAIT:
tcpm_set_cc(port, tcpm_rp_cc(port));
- if (!port->vbus_present && tcpm_port_is_source(port))
- tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
- else
+ if (port->max_wait == 0) {
+ port->max_wait = jiffies +
+ msecs_to_jiffies(PD_T_DRP_TRY);
tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
PD_T_DRP_TRY);
+ } else {
+ if (time_is_after_jiffies(port->max_wait))
+ tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
+ jiffies_to_msecs(port->max_wait -
+ jiffies));
+ else
+ tcpm_set_state(port, SNK_UNATTACHED, 0);
+ }
+ break;
+ case SRC_TRYWAIT_DEBOUNCE:
+ tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
break;
case SRC_TRYWAIT_UNATTACHED:
tcpm_set_state(port, SNK_UNATTACHED, 0);
@@ -2898,11 +2915,10 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
case SRC_TRYWAIT:
/* Hand over to state machine if needed */
if (!port->vbus_present && tcpm_port_is_source(port))
- new_state = SRC_ATTACHED;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
-
- if (new_state != port->delayed_state)
+ tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0);
+ break;
+ case SRC_TRYWAIT_DEBOUNCE:
+ if (port->vbus_present || !tcpm_port_is_source(port))
tcpm_set_state(port, SRC_TRYWAIT, 0);
break;
case SNK_TRY_WAIT:
@@ -2990,9 +3006,10 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
/* Do nothing, waiting for timeout */
break;
case SRC_TRYWAIT:
- /* Hand over to state machine if needed */
- if (port->delayed_state != SRC_TRYWAIT_UNATTACHED)
- tcpm_set_state(port, SRC_TRYWAIT, 0);
+ /* Do nothing, Waiting for Rd to be detected */
+ break;
+ case SRC_TRYWAIT_DEBOUNCE:
+ tcpm_set_state(port, SRC_TRYWAIT, 0);
break;
case SNK_TRY_WAIT:
if (tcpm_port_is_sink(port)) {
@@ -3039,11 +3056,7 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
case SRC_TRYWAIT:
/* Hand over to state machine if needed */
if (tcpm_port_is_source(port))
- new_state = SRC_ATTACHED;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
- if (new_state != port->delayed_state)
- tcpm_set_state(port, SRC_TRYWAIT, 0);
+ tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0);
break;
case SNK_TRY_WAIT:
if (!tcpm_port_is_sink(port))
--
2.14.1.342.g6490525c54-goog
next prev parent reply other threads:[~2017-08-28 17:24 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-28 17:23 [PATCH 01/11 v3] staging: typec: tcpm: set port type callback Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 02/11 v3] staging: typec: tcpm: Check for port type for Try.SRC/Try.SNK Badhri Jagan Sridharan
2017-08-28 17:23 ` Badhri Jagan Sridharan [this message]
2017-08-28 17:23 ` [PATCH 04/11 v3] staging: usb: tcpm: usb: type-c: tcpm: Check for Rp for tPDDebounce Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 05/11 v3] staging: typec: tcpm: Follow Try.SRC exit requirements Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 06/11 v3] staging: typec: tcpm: Comply with TryWait.SNK State Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 07/11 v3] staging: typec: tcpm: Consider port_type while determining unattached_state Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 08/11 v3] staging: typec: tcpm: add cc change handling in src states Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 09/11 v3] staging: typec: tcpm: typec: tcpm: Wait for CC debounce before PD excg Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 10/11 v3] staging: typec: tcpm: Do not send PING msgs in TCPM Badhri Jagan Sridharan
2017-08-28 17:23 ` [PATCH 11/11 v3] staging: typec: tcpm: Switch to PORT_RESET instead of SNK_UNATTACHED Badhri Jagan Sridharan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170828172322.7166-3-Badhri@google.com \
--to=badhri@google.com \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome