Skip to content

Commit 3f58c1f

Browse files
glneoJassi Brar
authored andcommitted
mailbox: omap: Remove kernel FIFO message queuing
The kernel FIFO queue has a couple issues. The biggest issue is that it causes extra latency in a path that can be used in real-time tasks, such as communication with real-time remote processors. The whole FIFO idea itself looks to be a leftover from before the unified mailbox framework. The current mailbox framework expects mbox_chan_received_data() to be called with data immediately as it arrives. Remove the FIFO and pass the messages to the mailbox framework directly as part of a threaded IRQ handler. Signed-off-by: Andrew Davis <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 04a07a3 commit 3f58c1f

File tree

2 files changed

+5
-111
lines changed

2 files changed

+5
-111
lines changed

drivers/mailbox/Kconfig

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,6 @@ config OMAP2PLUS_MBOX
6868
OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you
6969
want to use OMAP2+ Mailbox framework support.
7070

71-
config OMAP_MBOX_KFIFO_SIZE
72-
int "Mailbox kfifo default buffer size (bytes)"
73-
depends on OMAP2PLUS_MBOX
74-
default 256
75-
help
76-
Specify the default size of mailbox's kfifo buffers (bytes).
77-
This can also be changed at runtime (via the mbox_kfifo_size
78-
module parameter).
79-
8071
config ROCKCHIP_MBOX
8172
bool "Rockchip Soc Integrated Mailbox Support"
8273
depends on ARCH_ROCKCHIP || COMPILE_TEST

drivers/mailbox/omap-mailbox.c

Lines changed: 5 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,6 @@ struct omap_mbox_fifo {
6565
u32 intr_bit;
6666
};
6767

68-
struct omap_mbox_queue {
69-
spinlock_t lock;
70-
struct kfifo fifo;
71-
struct work_struct work;
72-
struct omap_mbox *mbox;
73-
bool full;
74-
};
75-
7668
struct omap_mbox_match_data {
7769
u32 intr_type;
7870
};
@@ -90,7 +82,6 @@ struct omap_mbox_device {
9082
struct omap_mbox {
9183
const char *name;
9284
int irq;
93-
struct omap_mbox_queue *rxq;
9485
struct omap_mbox_device *parent;
9586
struct omap_mbox_fifo tx_fifo;
9687
struct omap_mbox_fifo rx_fifo;
@@ -99,10 +90,6 @@ struct omap_mbox {
9990
bool send_no_irq;
10091
};
10192

102-
static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
103-
module_param(mbox_kfifo_size, uint, S_IRUGO);
104-
MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
105-
10693
static inline
10794
unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
10895
{
@@ -202,30 +189,6 @@ static void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
202189
mbox_write_reg(mbox->parent, bit, irqdisable);
203190
}
204191

205-
/*
206-
* Message receiver(workqueue)
207-
*/
208-
static void mbox_rx_work(struct work_struct *work)
209-
{
210-
struct omap_mbox_queue *mq =
211-
container_of(work, struct omap_mbox_queue, work);
212-
u32 msg;
213-
int len;
214-
215-
while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
216-
len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
217-
WARN_ON(len != sizeof(msg));
218-
219-
mbox_chan_received_data(mq->mbox->chan, (void *)(uintptr_t)msg);
220-
spin_lock_irq(&mq->lock);
221-
if (mq->full) {
222-
mq->full = false;
223-
omap_mbox_enable_irq(mq->mbox, IRQ_RX);
224-
}
225-
spin_unlock_irq(&mq->lock);
226-
}
227-
}
228-
229192
/*
230193
* Mailbox interrupt handler
231194
*/
@@ -238,27 +201,15 @@ static void __mbox_tx_interrupt(struct omap_mbox *mbox)
238201

239202
static void __mbox_rx_interrupt(struct omap_mbox *mbox)
240203
{
241-
struct omap_mbox_queue *mq = mbox->rxq;
242204
u32 msg;
243-
int len;
244205

245206
while (!mbox_fifo_empty(mbox)) {
246-
if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
247-
omap_mbox_disable_irq(mbox, IRQ_RX);
248-
mq->full = true;
249-
goto nomem;
250-
}
251-
252207
msg = mbox_fifo_read(mbox);
253-
254-
len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
255-
WARN_ON(len != sizeof(msg));
208+
mbox_chan_received_data(mbox->chan, (void *)(uintptr_t)msg);
256209
}
257210

258-
/* no more messages in the fifo. clear IRQ source. */
211+
/* clear IRQ source. */
259212
ack_mbox_irq(mbox, IRQ_RX);
260-
nomem:
261-
schedule_work(&mbox->rxq->work);
262213
}
263214

264215
static irqreturn_t mbox_interrupt(int irq, void *p)
@@ -274,57 +225,15 @@ static irqreturn_t mbox_interrupt(int irq, void *p)
274225
return IRQ_HANDLED;
275226
}
276227

277-
static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
278-
void (*work)(struct work_struct *))
279-
{
280-
struct omap_mbox_queue *mq;
281-
unsigned int size;
282-
283-
if (!work)
284-
return NULL;
285-
286-
mq = kzalloc(sizeof(*mq), GFP_KERNEL);
287-
if (!mq)
288-
return NULL;
289-
290-
spin_lock_init(&mq->lock);
291-
292-
/* kfifo size sanity check: alignment and minimal size */
293-
size = ALIGN(mbox_kfifo_size, sizeof(u32));
294-
size = max_t(unsigned int, size, sizeof(u32));
295-
if (kfifo_alloc(&mq->fifo, size, GFP_KERNEL))
296-
goto error;
297-
298-
INIT_WORK(&mq->work, work);
299-
return mq;
300-
301-
error:
302-
kfree(mq);
303-
return NULL;
304-
}
305-
306-
static void mbox_queue_free(struct omap_mbox_queue *q)
307-
{
308-
kfifo_free(&q->fifo);
309-
kfree(q);
310-
}
311-
312228
static int omap_mbox_startup(struct omap_mbox *mbox)
313229
{
314230
int ret = 0;
315-
struct omap_mbox_queue *mq;
316-
317-
mq = mbox_queue_alloc(mbox, mbox_rx_work);
318-
if (!mq)
319-
return -ENOMEM;
320-
mbox->rxq = mq;
321-
mq->mbox = mbox;
322231

323-
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
324-
mbox->name, mbox);
232+
ret = request_threaded_irq(mbox->irq, NULL, mbox_interrupt,
233+
IRQF_ONESHOT, mbox->name, mbox);
325234
if (unlikely(ret)) {
326235
pr_err("failed to register mailbox interrupt:%d\n", ret);
327-
goto fail_request_irq;
236+
return ret;
328237
}
329238

330239
if (mbox->send_no_irq)
@@ -333,18 +242,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
333242
omap_mbox_enable_irq(mbox, IRQ_RX);
334243

335244
return 0;
336-
337-
fail_request_irq:
338-
mbox_queue_free(mbox->rxq);
339-
return ret;
340245
}
341246

342247
static void omap_mbox_fini(struct omap_mbox *mbox)
343248
{
344249
omap_mbox_disable_irq(mbox, IRQ_RX);
345250
free_irq(mbox->irq, mbox);
346-
flush_work(&mbox->rxq->work);
347-
mbox_queue_free(mbox->rxq);
348251
}
349252

350253
static int omap_mbox_chan_startup(struct mbox_chan *chan)

0 commit comments

Comments
 (0)