From 0cc67945ea5933d53db69606312cf52f553d1b81 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 31 Jul 2015 11:48:05 +0100 Subject: mailbox: switch to hrtimer for tx_complete polling The mailbox core uses jiffy based timer to handle polling for the transmit completion. If the client/protocol have/support notification of the last packet transmit completion via ACK packet, then we tick the Tx state machine immediately in the callback. However if the client doesn't support that mechanism we might end-up waiting for atleast a jiffy even though the remote is ready to receive the next request. This patch switches the timer used for that polling from jiffy-based to hrtimer-based so that we can support polling at much higher time resolution. Reported-and-suggested-by: Juri Lelli Signed-off-by: Sudeep Holla Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/mailbox') diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index c7fdb57fd166..6a4811f85705 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -26,8 +26,6 @@ static LIST_HEAD(mbox_cons); static DEFINE_MUTEX(con_mutex); -static void poll_txdone(unsigned long data); - static int add_to_rbuf(struct mbox_chan *chan, void *mssg) { int idx; @@ -88,7 +86,9 @@ exit: spin_unlock_irqrestore(&chan->lock, flags); if (!err && (chan->txdone_method & TXDONE_BY_POLL)) - poll_txdone((unsigned long)chan->mbox); + /* kick start the timer immediately to avoid delays */ + hrtimer_start(&chan->mbox->poll_hrt, ktime_set(0, 0), + HRTIMER_MODE_REL); } static void tx_tick(struct mbox_chan *chan, int r) @@ -112,9 +112,10 @@ static void tx_tick(struct mbox_chan *chan, int r) complete(&chan->tx_complete); } -static void poll_txdone(unsigned long data) +static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) { - struct mbox_controller *mbox = (struct mbox_controller *)data; + struct mbox_controller *mbox = + container_of(hrtimer, struct mbox_controller, poll_hrt); bool txdone, resched = false; int i; @@ -130,9 +131,11 @@ static void poll_txdone(unsigned long data) } } - if (resched) - mod_timer(&mbox->poll, jiffies + - msecs_to_jiffies(mbox->txpoll_period)); + if (resched) { + hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); + return HRTIMER_RESTART; + } + return HRTIMER_NORESTART; } /** @@ -451,9 +454,9 @@ int mbox_controller_register(struct mbox_controller *mbox) txdone = TXDONE_BY_ACK; if (txdone == TXDONE_BY_POLL) { - mbox->poll.function = &poll_txdone; - mbox->poll.data = (unsigned long)mbox; - init_timer(&mbox->poll); + hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + mbox->poll_hrt.function = txdone_hrtimer; } for (i = 0; i < mbox->num_chans; i++) { @@ -495,7 +498,7 @@ void mbox_controller_unregister(struct mbox_controller *mbox) mbox_free_channel(&mbox->chans[i]); if (mbox->txdone_poll) - del_timer_sync(&mbox->poll); + hrtimer_cancel(&mbox->poll_hrt); mutex_unlock(&con_mutex); } -- cgit v1.2.3