summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mailbox/mailbox.c27
1 files changed, 15 insertions, 12 deletions
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 @@
26static LIST_HEAD(mbox_cons); 26static LIST_HEAD(mbox_cons);
27static DEFINE_MUTEX(con_mutex); 27static DEFINE_MUTEX(con_mutex);
28 28
29static void poll_txdone(unsigned long data);
30
31static int add_to_rbuf(struct mbox_chan *chan, void *mssg) 29static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
32{ 30{
33 int idx; 31 int idx;
@@ -88,7 +86,9 @@ exit:
88 spin_unlock_irqrestore(&chan->lock, flags); 86 spin_unlock_irqrestore(&chan->lock, flags);
89 87
90 if (!err && (chan->txdone_method & TXDONE_BY_POLL)) 88 if (!err && (chan->txdone_method & TXDONE_BY_POLL))
91 poll_txdone((unsigned long)chan->mbox); 89 /* kick start the timer immediately to avoid delays */
90 hrtimer_start(&chan->mbox->poll_hrt, ktime_set(0, 0),
91 HRTIMER_MODE_REL);
92} 92}
93 93
94static void tx_tick(struct mbox_chan *chan, int r) 94static void tx_tick(struct mbox_chan *chan, int r)
@@ -112,9 +112,10 @@ static void tx_tick(struct mbox_chan *chan, int r)
112 complete(&chan->tx_complete); 112 complete(&chan->tx_complete);
113} 113}
114 114
115static void poll_txdone(unsigned long data) 115static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer)
116{ 116{
117 struct mbox_controller *mbox = (struct mbox_controller *)data; 117 struct mbox_controller *mbox =
118 container_of(hrtimer, struct mbox_controller, poll_hrt);
118 bool txdone, resched = false; 119 bool txdone, resched = false;
119 int i; 120 int i;
120 121
@@ -130,9 +131,11 @@ static void poll_txdone(unsigned long data)
130 } 131 }
131 } 132 }
132 133
133 if (resched) 134 if (resched) {
134 mod_timer(&mbox->poll, jiffies + 135 hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period));
135 msecs_to_jiffies(mbox->txpoll_period)); 136 return HRTIMER_RESTART;
137 }
138 return HRTIMER_NORESTART;
136} 139}
137 140
138/** 141/**
@@ -451,9 +454,9 @@ int mbox_controller_register(struct mbox_controller *mbox)
451 txdone = TXDONE_BY_ACK; 454 txdone = TXDONE_BY_ACK;
452 455
453 if (txdone == TXDONE_BY_POLL) { 456 if (txdone == TXDONE_BY_POLL) {
454 mbox->poll.function = &poll_txdone; 457 hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC,
455 mbox->poll.data = (unsigned long)mbox; 458 HRTIMER_MODE_REL);
456 init_timer(&mbox->poll); 459 mbox->poll_hrt.function = txdone_hrtimer;
457 } 460 }
458 461
459 for (i = 0; i < mbox->num_chans; i++) { 462 for (i = 0; i < mbox->num_chans; i++) {
@@ -495,7 +498,7 @@ void mbox_controller_unregister(struct mbox_controller *mbox)
495 mbox_free_channel(&mbox->chans[i]); 498 mbox_free_channel(&mbox->chans[i]);
496 499
497 if (mbox->txdone_poll) 500 if (mbox->txdone_poll)
498 del_timer_sync(&mbox->poll); 501 hrtimer_cancel(&mbox->poll_hrt);
499 502
500 mutex_unlock(&con_mutex); 503 mutex_unlock(&con_mutex);
501} 504}