diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mailbox/mailbox.c | 27 |
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 @@ | |||
26 | static LIST_HEAD(mbox_cons); | 26 | static LIST_HEAD(mbox_cons); |
27 | static DEFINE_MUTEX(con_mutex); | 27 | static DEFINE_MUTEX(con_mutex); |
28 | 28 | ||
29 | static void poll_txdone(unsigned long data); | ||
30 | |||
31 | static int add_to_rbuf(struct mbox_chan *chan, void *mssg) | 29 | static 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 | ||
94 | static void tx_tick(struct mbox_chan *chan, int r) | 94 | static 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 | ||
115 | static void poll_txdone(unsigned long data) | 115 | static 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 | } |