diff options
author | Andrew Bresticker <abrestic@chromium.org> | 2014-10-30 16:01:07 -0400 |
---|---|---|
committer | Jassi Brar <jaswinder.singh@linaro.org> | 2014-11-27 01:51:27 -0500 |
commit | 52a49306d7d19ef127e6d6f4fd92f84d4864296f (patch) | |
tree | 9e6608b633caf55d6552b124654af4a16cb79d6f | |
parent | 0df1f2487d2f0d04703f142813d53615d62a1da4 (diff) |
mailbox: Don't unnecessarily re-arm the polling timer
poll_txdone() will unconditionally re-arm the polling timer if there was
an active request, even if the active request completed and no other
requests were submitted. This is fixed by:
- only re-arming the timer if the controller reported that the current
transmission has not completed, and,
- moving the call to poll_txdone() into msg_submit() so that the
controller gets polled (and the timer re-armed, if necessary) whenever
a new message is submitted.
Signed-off-by: Andrew Bresticker <abrestic@chromium.org>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
-rw-r--r-- | drivers/mailbox/mailbox.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index afcb430508ec..c281e5562876 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c | |||
@@ -28,6 +28,8 @@ | |||
28 | static LIST_HEAD(mbox_cons); | 28 | static LIST_HEAD(mbox_cons); |
29 | static DEFINE_MUTEX(con_mutex); | 29 | static DEFINE_MUTEX(con_mutex); |
30 | 30 | ||
31 | static void poll_txdone(unsigned long data); | ||
32 | |||
31 | static int add_to_rbuf(struct mbox_chan *chan, void *mssg) | 33 | static int add_to_rbuf(struct mbox_chan *chan, void *mssg) |
32 | { | 34 | { |
33 | int idx; | 35 | int idx; |
@@ -60,7 +62,7 @@ static void msg_submit(struct mbox_chan *chan) | |||
60 | unsigned count, idx; | 62 | unsigned count, idx; |
61 | unsigned long flags; | 63 | unsigned long flags; |
62 | void *data; | 64 | void *data; |
63 | int err; | 65 | int err = -EBUSY; |
64 | 66 | ||
65 | spin_lock_irqsave(&chan->lock, flags); | 67 | spin_lock_irqsave(&chan->lock, flags); |
66 | 68 | ||
@@ -84,6 +86,9 @@ static void msg_submit(struct mbox_chan *chan) | |||
84 | } | 86 | } |
85 | exit: | 87 | exit: |
86 | spin_unlock_irqrestore(&chan->lock, flags); | 88 | spin_unlock_irqrestore(&chan->lock, flags); |
89 | |||
90 | if (!err && chan->txdone_method == TXDONE_BY_POLL) | ||
91 | poll_txdone((unsigned long)chan->mbox); | ||
87 | } | 92 | } |
88 | 93 | ||
89 | static void tx_tick(struct mbox_chan *chan, int r) | 94 | static void tx_tick(struct mbox_chan *chan, int r) |
@@ -117,10 +122,11 @@ static void poll_txdone(unsigned long data) | |||
117 | struct mbox_chan *chan = &mbox->chans[i]; | 122 | struct mbox_chan *chan = &mbox->chans[i]; |
118 | 123 | ||
119 | if (chan->active_req && chan->cl) { | 124 | if (chan->active_req && chan->cl) { |
120 | resched = true; | ||
121 | txdone = chan->mbox->ops->last_tx_done(chan); | 125 | txdone = chan->mbox->ops->last_tx_done(chan); |
122 | if (txdone) | 126 | if (txdone) |
123 | tx_tick(chan, 0); | 127 | tx_tick(chan, 0); |
128 | else | ||
129 | resched = true; | ||
124 | } | 130 | } |
125 | } | 131 | } |
126 | 132 | ||
@@ -252,9 +258,6 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg) | |||
252 | 258 | ||
253 | msg_submit(chan); | 259 | msg_submit(chan); |
254 | 260 | ||
255 | if (chan->txdone_method == TXDONE_BY_POLL) | ||
256 | poll_txdone((unsigned long)chan->mbox); | ||
257 | |||
258 | if (chan->cl->tx_block && chan->active_req) { | 261 | if (chan->cl->tx_block && chan->active_req) { |
259 | unsigned long wait; | 262 | unsigned long wait; |
260 | int ret; | 263 | int ret; |