hsi_ffl_tty.c: Adding a WAKE post-boot handshake
authorOlivier Stoltz Douchet <olivierx.stoltz-douchet@intel.com>
Thu, 15 Dec 2011 17:45:33 +0000 (18:45 +0100)
committerbuildbot <buildbot@intel.com>
Mon, 19 Dec 2011 22:01:26 +0000 (14:01 -0800)
BZ: 17580

This patch is adding an ACWAKE post modem boot handshake during the TTY
activate callback to ensure that the modem has boot-up prior to have the TTY
interface up and running.

This handshake is based on the fact that the 6260 modem is asserting its CAWAKE
line after it has boot whenever the CAWAKE line is asserted. This patch is
simply asserting the ACWAKE line and waiting for the CAWAKE line at the very
end of the activate TTY callback function. This way the modem is always up and
ready when the TTY interface is active, shall it be at boot time or further to
a reset.

Change-Id: I67385f754cc845997145deca70fc6035880c2fb2
Signed-off-by: Olivier Stoltz Douchet <olivierx.stoltz-douchet@intel.com>
Reviewed-on: http://android.intel.com:8080/27670
Reviewed-by: Gross, Mark <mark.gross@intel.com>
Reviewed-by: Koskinen, Ilkka <ilkka.koskinen@intel.com>
Reviewed-by: Akue, LoicX <loicx.akue@intel.com>
Reviewed-by: Morel, YannickX <yannickx.morel@intel.com>
Reviewed-by: Predon, Frederic <frederic.predon@intel.com>
Reviewed-by: Lucas, GuillaumeX <guillaumex.lucas@intel.com>
Reviewed-by: Robert, Denis <denis.robert@intel.com>
Tested-by: Robert, Denis <denis.robert@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/hsi/clients/hsi_ffl_tty.c

index be37a65..d6bad08 100644 (file)
@@ -26,6 +26,9 @@
 /* Set the following to use the IPC error recovery mechanism */
 #undef USE_IPC_ERROR_RECOVERY
 
+/* Set the following to use the WAKE post boot handshake */
+#define USE_WAKE_POST_BOOT_HANDSHAKE
+
 #include <linux/log2.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
@@ -71,6 +74,9 @@
 #define FFL_MIN_TX_BUFFERING   65536
 #define FFL_MIN_RX_BUFFERING   65536
 
+/* Modem post book wake handshake timeout value (10 seconds) */
+#define POST_BOOT_HANDSHAKE_TIMEOUT_JIFFIES    (msecs_to_jiffies(10000))
+
 /* Error recovery related timings */
 #define RECOVERY_TO_NORMAL_DELAY_JIFFIES       (usecs_to_jiffies(100000))
 #define RECOVERY_TX_DRAIN_TIMEOUT_JIFFIES      (usecs_to_jiffies(100000))
@@ -205,11 +211,15 @@ struct ffl_hangup_ctx {
  * @cd_irq: the modem core dump interrupt line
  * @irq: the modem reset interrupt line
  * @ongoing: a flag stating that a reset is ongoing
+ * @modem_awake_event: modem WAKE post boot handshake event
  */
 struct ffl_reset_ctx {
        int                     cd_irq;
        int                     irq;
        int                     ongoing;
+#ifdef USE_WAKE_POST_BOOT_HANDSHAKE
+       wait_queue_head_t       modem_awake_event;
+#endif
 };
 
 #ifdef USE_IPC_ERROR_RECOVERY
@@ -1119,6 +1129,26 @@ static __must_check int ffl_tx_write_pipe_is_clean(struct ffl_xfer_ctx *ctx)
        return ret;
 }
 
+#ifdef USE_WAKE_POST_BOOT_HANDSHAKE
+/**
+ * ffl_modem_is_awake - checks if the RX side is active or not
+ * @ctx: a reference to the RX context to consider
+ *
+ * This helper function is returning a non-zero value if the RX state is active.
+ */
+static __must_check int ffl_modem_is_awake(struct ffl_xfer_ctx *ctx)
+{
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ctx->lock, flags);
+       ret = _ffl_ctx_is_state(ctx, ACTIVE);
+       spin_unlock_irqrestore(&ctx->lock, flags);
+
+       return ret;
+}
+#endif
+
 /*
  * State machines
  */
@@ -1208,6 +1238,9 @@ static void ffl_start_rx(struct hsi_client *cl)
 
        spin_lock_irqsave(&ctx->lock, flags);
        _ffl_ctx_set_state(ctx, ACTIVE);
+#ifdef USE_WAKE_POST_BOOT_HANDSHAKE
+       wake_up(&main_ctx->reset.modem_awake_event);
+#endif
        spin_unlock_irqrestore(&ctx->lock, flags);
 }
 
@@ -1957,6 +1990,21 @@ static int ffl_tty_port_activate(struct tty_port *port, struct tty_struct *tty)
        _ffl_ctx_clear_flag(tx_ctx, TTY_OFF_BIT|ERROR_RECOVERY_TX_DRAINED_BIT);
        spin_unlock_irqrestore(&tx_ctx->lock, flags);
 
+#ifdef USE_WAKE_POST_BOOT_HANDSHAKE
+       /* Wait for the modem post boot WAKE handshake before continuing */
+       hsi_start_tx(ctx->client);
+       wait_event_interruptible_timeout(ctx->reset.modem_awake_event,
+                                        ffl_modem_is_awake(rx_ctx),
+                                        POST_BOOT_HANDSHAKE_TIMEOUT_JIFFIES);
+       err = !ffl_modem_is_awake(rx_ctx);
+       hsi_stop_tx(ctx->client);
+       if (unlikely(err)) {
+               pr_err(DRVNAME ": Modem wakeup failed (-EXDEV)");
+               hsi_release_port(ctx->client);
+               return -EXDEV;
+       }
+#endif
+
        return 0;
 }
 
@@ -3218,6 +3266,10 @@ static int ffl_reset_ctx_init(struct ffl_reset_ctx *ctx_reset,
                        mdm_rst_out, "RST_OUT");
        ffl_request_irq(cd_irq, IRQF_TRIGGER_RISING, fcdp_rb, "CORE DUMP");
 
+#ifdef USE_WAKE_POST_BOOT_HANDSHAKE
+       init_waitqueue_head(&ctx_reset->modem_awake_event);
+#endif
+
        modem_power(ctx);
 
        return 0;