Esempio n. 1
0
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);
	}
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}