/* * Main virtqueue message workqueue function * * This function is executed upon scheduling of the keystone remoteproc * driver's workqueue. The workqueue is scheduled by the vring ISR handler. * * There is no payload message indicating the virtqueue index as is the * case with mailbox-based implementations on OMAP family. As such, this * handler processes both the Tx and Rx virtqueue indices on every invocation. * The rproc_vq_interrupt function can detect if there are new unprocessed * messages or not (returns IRQ_NONE vs IRQ_HANDLED), but there is no need * to check for these return values. The index 0 triggering will process all * pending Rx buffers, and the index 1 triggering will process all newly * available Tx buffers and will wakeup any potentially blocked senders. * * NOTE: * 1. A payload could be added by using some of the source bits in the * IPC interrupt generation registers, but this would need additional * changes to the overall IPC stack, and currently there are no benefits * of adapting that approach. * 2. The current logic is based on an inherent design assumption of supporting * only 2 vrings, but this can be changed if needed. */ static void handle_event(struct work_struct *work) { struct keystone_rproc *ksproc = container_of(work, struct keystone_rproc, workqueue); rproc_vq_interrupt(ksproc->rproc, 0); rproc_vq_interrupt(ksproc->rproc, 1); }
/** * handle_event() - inbound virtqueue message workqueue function * * This function is registered as a kernel thread and is scheduled by the * kernel handler. */ static irqreturn_t handle_event(int irq, void *p) { struct rproc *rproc = (struct rproc *)p; /* Process incoming buffers on all our vrings */ rproc_vq_interrupt(rproc, 0); rproc_vq_interrupt(rproc, 1); return IRQ_HANDLED; }
/* Received a kick from a modem, kick the virtqueue */ static void sproc_kick_callback(struct ste_modem_device *mdev, int vqid) { struct sproc *sproc = mdev->drv_data; if (rproc_vq_interrupt(sproc->rproc, vqid) == IRQ_NONE) sproc_dbg(sproc, "no message was found in vqid %d\n", vqid); }
static void handle_event(struct zynqmp_r5_rproc_pdata *local) { flush_cache_all(); if (rproc_vq_interrupt(local->rproc, 0) == IRQ_NONE) dev_dbg(&remoteprocdev[local->rpu_id]->dev, \ "no message found in vqid 0\n"); }
static void handle_event(struct work_struct *work) { struct mb_rproc_pdata *local = platform_get_drvdata(remoteprocdev); flush_cache_all(); outer_flush_range(local->mem_start, local->mem_end); if (rproc_vq_interrupt(local->rproc, 0) == IRQ_NONE) dev_info(&remoteprocdev->dev, "no message found in vqid 0\n"); }
static int _vq_interrupt_thread(struct _thread_data *d) { struct omap_rproc *oproc = d->rproc->priv; struct device *dev = d->rproc->dev.parent; /* msg contains the index of the triggered vring */ if (rproc_vq_interrupt(d->rproc, d->msg) == IRQ_NONE) dev_dbg(dev, "no message was found in vqid 0x0\n"); kfree(d); atomic_dec(&oproc->thrd_cnt); return 0; }