static void __mbox_rx_interrupt(struct omap_mbox *mbox) { struct omap_mbox_queue *mq = mbox->rxq; mbox_msg_t msg; int len; while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); mq->full = true; goto nomem; } msg = mbox_fifo_read(mbox); len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); nomem: schedule_work(&mbox->rxq->work); }
/* * Message receiver(workqueue) */ static void mbox_rx_work(struct work_struct *work) { struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work); mbox_msg_t msg; int len; while (kfifo_len(&mq->fifo) >= sizeof(msg)) { len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); blocking_notifier_call_chain(&mq->mbox->notifier, len, (void *)msg); spin_lock_irq(&mq->lock); if (mq->full) { mq->full = false; if (!mbox_fifo_empty(mq->mbox)) { msg = mbox_fifo_read(mq->mbox); len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); /* WARN_ON(len != sizeof(msg));*/ } omap_mbox_enable_irq(mq->mbox, IRQ_RX); } spin_unlock_irq(&mq->lock); } }
static void __mbox_rx_interrupt(struct omap_mbox *mbox) { struct request *rq; mbox_msg_t msg; struct request_queue *q = mbox->rxq->queue; disable_mbox_irq(mbox, IRQ_RX); while (!mbox_fifo_empty(mbox)) { rq = blk_get_request(q, WRITE, GFP_ATOMIC); if (unlikely(!rq)) goto nomem; msg = mbox_fifo_read(mbox); rq->data = (void *)msg; if (unlikely(mbox_seq_test(mbox, msg))) { pr_info("mbox: Illegal seq bit!(%08x)\n", msg); if (mbox->err_notify) mbox->err_notify(); } blk_insert_request(q, rq, 0, NULL); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); enable_mbox_irq(mbox, IRQ_RX); nomem: schedule_work(&mbox->rxq->work); }
static void __mbox_rx_interrupt(struct omap_mbox *mbox) { struct omap_mbox_queue *mq = mbox->rxq; mbox_msg_t msg; int len; while (!mbox_fifo_empty(mbox)) { if (unlikely(__kfifo_len(mq->fifo) >= FIFO_SIZE - sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); rq_full = true; goto nomem; } msg = mbox_fifo_read(mbox); len = __kfifo_put(mq->fifo, (unsigned char *)&msg, sizeof(msg)); if (unlikely(len != sizeof(msg))) pr_err("%s: __kfifo_put anomaly detected\n", __func__); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); nomem: queue_work(mboxd, &mbox->rxq->work); }
static void __mbox_rx_interrupt(struct omap_mbox *mbox) { struct request *rq; mbox_msg_t msg; struct request_queue *q = mbox->rxq->queue; while (!mbox_fifo_empty(mbox)) { rq = blk_get_request(q, WRITE, GFP_ATOMIC); if (unlikely(!rq)) goto nomem; msg = mbox_fifo_read(mbox); blk_insert_request(q, rq, 0, (void *)msg); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); nomem: schedule_work(&mbox->rxq->work); }