From ee08fc73fde63b6fab7714b6619da2da73f9ae36 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 27 Jul 2017 22:43:52 +0800 Subject: [PATCH] MLK-16013-24 staging: typec: tcpm: use hrtimer for send response As the sender response timer have very small margin(25~30ms), so use a hrtimer to handle it. Reviewed-by: Peter Chen Signed-off-by: Li Jun --- drivers/staging/typec/tcpm.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index b0abe97b622e..c78453ce5ab2 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -279,6 +280,9 @@ struct tcpm_port { struct typec_altmode *partner_altmode[SVID_DISCOVERY_MAX]; struct typec_altmode *port_altmode[SVID_DISCOVERY_MAX]; + /* Send response timer */ + struct hrtimer snd_res_timer; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -1292,6 +1296,7 @@ static void tcpm_pd_data_request(struct tcpm_port *port, break; } port->sink_request = le32_to_cpu(msg->payload[0]); + hrtimer_cancel(&port->snd_res_timer); tcpm_set_state(port, SRC_NEGOTIATE_CAPABILITIES, 0); break; case PD_DATA_SINK_CAP: @@ -1343,6 +1348,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_queue_message(port, PD_MSG_DATA_SINK_CAP); break; default: + hrtimer_cancel(&port->snd_res_timer); tcpm_set_state(port, SOFT_RESET_SEND, 0); break; } @@ -1383,6 +1389,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, case PD_CTRL_WAIT: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: + hrtimer_cancel(&port->snd_res_timer); /* USB PD specification, Figure 8-43 */ if (port->explicit_contract) next_state = SNK_READY; @@ -1412,6 +1419,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, case PD_CTRL_ACCEPT: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: + hrtimer_cancel(&port->snd_res_timer); tcpm_set_state(port, SNK_TRANSITION_SINK, 0); break; case SOFT_RESET_SEND: @@ -2135,6 +2143,16 @@ static void tcpm_swap_complete(struct tcpm_port *port, int result) } } +static enum hrtimer_restart tcpm_sender_res_handle(struct hrtimer *data) +{ + struct tcpm_port *port = container_of(data, struct tcpm_port, + snd_res_timer); + + tcpm_log_force(port, "Sender response timeout!"); + tcpm_set_state(port, HARD_RESET_SEND, 0); + return HRTIMER_NORESTART; +} + static void run_state_machine(struct tcpm_port *port) { int ret; @@ -2244,8 +2262,9 @@ static void run_state_machine(struct tcpm_port *port) /* port->hard_reset_count = 0; */ port->caps_count = 0; port->pd_capable = true; - tcpm_set_state_cond(port, hard_reset_state(port), - PD_T_SEND_SOURCE_CAP); + hrtimer_start(&port->snd_res_timer, + ms_to_ktime(PD_T_SENDER_RESPONSE), + HRTIMER_MODE_REL); } break; case SRC_NEGOTIATE_CAPABILITIES: @@ -2446,8 +2465,9 @@ static void run_state_machine(struct tcpm_port *port) /* Let the Source send capabilities again. */ tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); } else { - tcpm_set_state_cond(port, hard_reset_state(port), - PD_T_SENDER_RESPONSE); + hrtimer_start(&port->snd_res_timer, + ms_to_ktime(PD_T_SENDER_RESPONSE), + HRTIMER_MODE_REL); } break; case SNK_TRANSITION_SINK: @@ -3515,6 +3535,9 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) } } + hrtimer_init(&port->snd_res_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + port->snd_res_timer.function = tcpm_sender_res_handle; + tcpm_debugfs_init(port); mutex_lock(&port->lock); tcpm_init(port); -- 2.17.1