From 14e851bb69fb6d6e4fa14e57111046bfaf6138b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= <megi@xff.cz>
Date: Sat, 2 Nov 2019 15:09:01 +0100
Subject: [PATCH 125/463] mailbox: Allow to run mailbox while timekeeping is
 suspended

This makes it possible to send messages from CPU suspend finisher.

We simply implement cl->tx_block using a busywait loop when
timekeeping is suspended, instead of using hrtimer.

Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
 drivers/mailbox/mailbox.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index ebff3baf30451..9d6656a0dc385 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -84,10 +84,12 @@ static void msg_submit(struct mbox_chan *chan)
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
-		/* kick start the timer immediately to avoid delays */
-		spin_lock_irqsave(&chan->mbox->poll_hrt_lock, flags);
-		hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
-		spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags);
+		if (!timekeeping_suspended) {
+			/* kick start the timer immediately to avoid delays */
+			spin_lock_irqsave(&chan->mbox->poll_hrt_lock, flags);
+			hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
+			spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags);
+		}
 	}
 }
 
@@ -269,6 +271,24 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
 
 	msg_submit(chan);
 
+	if (chan->cl->tx_block && timekeeping_suspended) {
+		int i = chan->cl->tx_tout * 10;
+		bool txdone;
+
+		while (i--) {
+			txdone = chan->mbox->ops->last_tx_done(chan);
+			if (txdone) {
+				tx_tick(chan, 0);
+				return 0;
+			}
+
+			udelay(100);
+		}
+
+		tx_tick(chan, -ETIME);
+		return -ETIME;
+	}
+
 	if (chan->cl->tx_block) {
 		unsigned long wait;
 		int ret;
-- 
2.46.0

