From e5ff665348dd0933009d6083d634296ea987531d Mon Sep 17 00:00:00 2001 From: Olivier Stoltz Douchet Date: Thu, 1 Dec 2011 15:38:18 +0100 Subject: [PATCH] [PORT FROM R2] hsi_ffl_tty.c: manage system time changes BZ: 15919 Should a system time change happen between a stop_tx and start_tx then a delay of the same duration as the time change can be observed in the write function. As the write function cannot exit prior to the expiration of this delay, the system is detecting an unresponsive write request and some mechanism is rebooting the platform. The patch presented below is simply casting the result of the time difference to an unsigned integer (instead of a signed one) so that should the new time be set prior to the current time, the time difference will be positive and no delay will be taken. One can argue that the delay will not be respected in such cases, but it is not possible to guarantee such delays without adding a new real timer. Change-Id: I46b2ecdf43e6070417cdb6b0f527d5c6639ec89e Orig-change-Id: I51413a04a9aa9309d27f27268d642c1a79796dea Signed-off-by: Olivier Stoltz Douchet Reviewed-on: http://android.intel.com:8080/31428 Reviewed-by: Pillet, VincentX Reviewed-by: Predon, Frederic Reviewed-by: Lebsir, SamiX Tested-by: Lebsir, SamiX Reviewed-by: buildbot Tested-by: buildbot --- drivers/hsi/clients/hsi_ffl_tty.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/hsi/clients/hsi_ffl_tty.c b/drivers/hsi/clients/hsi_ffl_tty.c index 2aaf97a..7690bc0 100644 --- a/drivers/hsi/clients/hsi_ffl_tty.c +++ b/drivers/hsi/clients/hsi_ffl_tty.c @@ -263,6 +263,9 @@ struct ffl_ctx { struct tty_port tty_prt; wait_queue_head_t tx_full_pipe_clean_event; wait_queue_head_t tx_write_pipe_clean_event; +#if (ACWAKE_MINIMAL_PULSE_UDELAY > 0) + ktime_t ktime_stop_tx; +#endif struct ffl_xfer_ctx tx; struct ffl_xfer_ctx rx; struct work_struct do_tty_forward; @@ -1173,7 +1176,9 @@ static void _ffl_start_tx(struct ffl_xfer_ctx *ctx, unsigned long *flags) _ffl_ctx_set_state(ctx, ACTIVE); spin_unlock_irqrestore(&ctx->lock, *flags); #if (ACWAKE_MINIMAL_PULSE_UDELAY > 0) - udelay(ACWAKE_MINIMAL_PULSE_UDELAY); + while (ktime_us_delta(ktime_get(), main_ctx->ktime_stop_tx) < + ACWAKE_MINIMAL_PULSE_UDELAY) + cpu_relax(); #endif err = hsi_start_tx(main_ctx->client); spin_lock_irqsave(&ctx->lock, *flags); @@ -1203,6 +1208,9 @@ static void _ffl_stop_tx(struct ffl_xfer_ctx *ctx, unsigned long *flags) main_ctx = container_of(ctx, struct ffl_ctx, tx); spin_unlock_irqrestore(&ctx->lock, *flags); hsi_stop_tx(main_ctx->client); +#if (ACWAKE_MINIMAL_PULSE_UDELAY > 0) + main_ctx->ktime_stop_tx = ktime_get(); +#endif spin_lock_irqsave(&ctx->lock, *flags); } } -- 2.7.4