msm: tty: update receive room just before writing data to the ldisc

There is a corner case in the tty driver where the value of
tty->receive_room is not being updated before writing data to
the line discipline. When this happens, data is lost because
of failure to re-submit any remaining data to the ldisc.

This fix is dependent on a new tty flag that is set only when
the tty driver is used for efs sync betweem the mdm modem and
the applications processor.

CRs-Fixed: 358868
Change-Id: I0ba02980504b4d8187b8c83111c2c883d194efa2
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 6c9b7cd..ccbaa6d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -418,6 +418,8 @@
 			int count;
 			char *char_buf;
 			unsigned char *flag_buf;
+			unsigned int left = 0;
+			unsigned int max_space;
 
 			count = head->commit - head->read;
 			if (!count) {
@@ -432,10 +434,33 @@
 			   line discipline as we want to empty the queue */
 			if (test_bit(TTY_FLUSHPENDING, &tty->flags))
 				break;
+
+			/* update receive room */
+			spin_lock(&tty->read_lock);
+			if (tty->update_room_in_ldisc) {
+				if ((tty->read_cnt == N_TTY_BUF_SIZE - 1) &&
+					(tty->receive_room ==
+						N_TTY_BUF_SIZE - 1))
+					tty->rr_bug++;
+				left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+			}
+			spin_unlock(&tty->read_lock);
+
 			if (!tty->receive_room)
 				break;
-			if (count > tty->receive_room)
-				count = tty->receive_room;
+
+			if (tty->update_room_in_ldisc && !left) {
+				schedule_work(&tty->buf.work);
+				break;
+			}
+
+			if (tty->update_room_in_ldisc)
+				max_space = min(left, tty->receive_room);
+			else
+				max_space = tty->receive_room;
+
+			if (count > max_space)
+				count = max_space;
 			char_buf = head->char_buf_ptr + head->read;
 			flag_buf = head->flag_buf_ptr + head->read;
 			head->read += count;