66 lines
1.9 KiB
Diff
66 lines
1.9 KiB
Diff
|
From 2e4db40284f68bdebe0e7ef5f9cd283e67dc11ae 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 027/464] 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 adf36c05fa43..e514abc1abd5 100644
|
||
|
--- a/drivers/mailbox/mailbox.c
|
||
|
+++ b/drivers/mailbox/mailbox.c
|
||
|
@@ -83,10 +83,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);
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -268,6 +270,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.34.1
|
||
|
|