Merge tag 'v4.4-rc7'
[firefly-linux-kernel-4.4.55.git] / drivers / mailbox / mailbox.c
index c7fdb57fd166cbf9cb8a0035c56f67a75ff8aa0a..6a4811f857056aaa64baff75265902b59be12ac9 100644 (file)
@@ -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);
 }