tty: n_smux: Add function to determine if remote side is active

For subsystem restart unit tests, we need to know when the remote system
is back up to avoid having to add fixed delays.

Add private function to allow checking to see if the remote side is
active.

Change-Id: Ide2f5e4aba01479c2dc1e8c3b4332da7da6ad0c5
Signed-off-by: Eric Holmberg <eholmber@codeaurora.org>
diff --git a/drivers/tty/n_smux.c b/drivers/tty/n_smux.c
index 5cb864f..14b8ca2 100644
--- a/drivers/tty/n_smux.c
+++ b/drivers/tty/n_smux.c
@@ -236,6 +236,7 @@
 	int is_initialized;
 	int platform_devs_registered;
 	int in_reset;
+	int remote_is_alive;
 	int ld_open_count;
 	struct tty_struct *tty;
 
@@ -444,6 +445,7 @@
 {
 	SMUX_ERR("%s: unrecoverable failure, waiting for ssr\n", __func__);
 	smux.in_reset = 1;
+	smux.remote_is_alive = 0;
 }
 
 /**
@@ -1974,10 +1976,20 @@
 			break;
 		case SMUX_WAKEUP_REQ:
 			SMUX_PWR("smux: smux: RX Wakeup REQ\n");
+			if (unlikely(!smux.remote_is_alive)) {
+				mutex_lock(&smux.mutex_lha0);
+				smux.remote_is_alive = 1;
+				mutex_unlock(&smux.mutex_lha0);
+			}
 			smux_handle_wakeup_req();
 			break;
 		case SMUX_WAKEUP_ACK:
 			SMUX_PWR("smux: smux: RX Wakeup ACK\n");
+			if (unlikely(!smux.remote_is_alive)) {
+				mutex_lock(&smux.mutex_lha0);
+				smux.remote_is_alive = 1;
+				mutex_unlock(&smux.mutex_lha0);
+			}
 			smux_handle_wakeup_ack();
 			break;
 		default:
@@ -2131,6 +2143,24 @@
 }
 
 /**
+ * Returns true if the remote side has acknowledged a wakeup
+ * request previously, so we know that the link is alive and active.
+ *
+ * @returns true for is alive, false for not alive
+ */
+bool smux_remote_is_active(void)
+{
+	bool is_active = false;
+
+	mutex_lock(&smux.mutex_lha0);
+	if (smux.remote_is_alive)
+		is_active = true;
+	mutex_unlock(&smux.mutex_lha0);
+
+	return is_active;
+}
+
+/**
  * Add channel to transmit-ready list and trigger transmit worker.
  *
  * @ch Channel to add
@@ -3449,6 +3479,7 @@
 		SMUX_DBG("smux: %s: ssr - before shutdown\n", __func__);
 		mutex_lock(&smux.mutex_lha0);
 		smux.in_reset = 1;
+		smux.remote_is_alive = 0;
 		mutex_unlock(&smux.mutex_lha0);
 		return NOTIFY_DONE;
 	} else if (code == SUBSYS_AFTER_POWERUP) {
@@ -3512,6 +3543,7 @@
 	smux.rx_activity_flag = 0;
 	smux.rx_state = SMUX_RX_IDLE;
 	smux.in_reset = 0;
+	smux.remote_is_alive = 0;
 	mutex_unlock(&smux.mutex_lha0);
 
 	return NOTIFY_DONE;
@@ -3635,6 +3667,7 @@
 
 	/* Disconnect from TTY */
 	smux.tty = NULL;
+	smux.remote_is_alive = 0;
 	mutex_unlock(&smux.mutex_lha0);
 	SMUX_DBG("smux: %s: ldisc complete\n", __func__);
 }
@@ -3756,6 +3789,7 @@
 	smux.tty = NULL;
 	smux.ld_open_count = 0;
 	smux.in_reset = 0;
+	smux.remote_is_alive = 0;
 	smux.is_initialized = 1;
 	smux.platform_devs_registered = 0;
 	smux_byte_loopback = 0;
diff --git a/drivers/tty/smux_private.h b/drivers/tty/smux_private.h
index b7fc1ce..195ee0f 100644
--- a/drivers/tty/smux_private.h
+++ b/drivers/tty/smux_private.h
@@ -180,6 +180,7 @@
 void smux_rx_state_machine(const unsigned char *data, int len, int flag);
 void smuxld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 			   char *fp, int count);
+bool smux_remote_is_active(void);
 
 /* testing parameters */
 extern int smux_byte_loopback;