Linux: TransportRpmsg: Fix Mutex Deadlock Issue
[ipc/ipcdev.git] / linux / patches / 3.8.0 / omapl138 / 0002-Allow-all-virtqueues-processing-in-rproc_vq_interrup.patch
1 From 39236bb3d4b19af05ee6cd7a60bdc8cf833e039f Mon Sep 17 00:00:00 2001
2 From: Robert Tivy <rtivy@ti.com>
3 Date: Fri, 8 Mar 2013 10:22:15 -0800
4 Subject: [PATCH v8 2/7] Allow "all virtqueues" processing in
5  rproc_vq_interrupt()
7 Add support to rproc_vq_interrupt() for a notifyid of -1 which will cause
8 all valid virtqueues to be processed.
10 Signed-off-by: Robert Tivy <rtivy@ti.com>
11 ---
12  drivers/remoteproc/remoteproc_virtio.c |   34 ++++++++++++++++++++++++++++----
13  1 file changed, 30 insertions(+), 4 deletions(-)
15 diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
16 index 9e198e5..07fa6cb 100644
17 --- a/drivers/remoteproc/remoteproc_virtio.c
18 +++ b/drivers/remoteproc/remoteproc_virtio.c
19 @@ -41,6 +41,21 @@ static void rproc_virtio_notify(struct virtqueue *vq)
20         rproc->ops->kick(rproc, notifyid);
21  }
22  
23 +/* processing function when iterating all virtqueues */
24 +static int rproc_vring_interrupt(int id, void *p, void *data)
25 +{
26 +       struct rproc_vring *rvring = (struct rproc_vring *)p;
27 +       irqreturn_t *retp = (irqreturn_t *)data;
28 +
29 +       if (!rvring->vq)
30 +               return 0;
31 +
32 +       if (vring_interrupt(0, rvring->vq) == IRQ_HANDLED)
33 +               *retp = IRQ_HANDLED;
34 +
35 +       return 0;
36 +}
37 +
38  /**
39   * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted
40   * @rproc: handle to the remote processor
41 @@ -52,18 +67,29 @@ static void rproc_virtio_notify(struct virtqueue *vq)
42   *
43   * Returns IRQ_NONE if no message was found in the @notifyid virtqueue,
44   * and otherwise returns IRQ_HANDLED.
45 + *
46 + * A @notifyid value of -1 can be passed in order to signal all available
47 + * virtqueues for this @rproc.  In this case this function returns IRQ_HANDLED
48 + * if any virtqueue contained a message, and IRQ_NONE if none of them did.
49   */
50  irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
51  {
52         struct rproc_vring *rvring;
53 +       irqreturn_t ret = IRQ_NONE;
54  
55         dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid);
56  
57 -       rvring = idr_find(&rproc->notifyids, notifyid);
58 -       if (!rvring || !rvring->vq)
59 -               return IRQ_NONE;
60 +       if (notifyid >= 0) {
61 +               rvring = idr_find(&rproc->notifyids, notifyid);
62 +               if (!rvring || !rvring->vq)
63 +                       return IRQ_NONE;
64  
65 -       return vring_interrupt(0, rvring->vq);
66 +               return vring_interrupt(0, rvring->vq);
67 +       } else {
68 +               idr_for_each(&rproc->notifyids, rproc_vring_interrupt, &ret);
69 +       }
70 +
71 +       return ret;
72  }
73  EXPORT_SYMBOL(rproc_vq_interrupt);
74  
75 -- 
76 1.7.9.4