Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[linux-block.git] / drivers / virtio / virtio_mmio.c
index c492a57531c613f6923a3751880e40ef34481d1c..a46a4a29e9295f7225bfbc631642e0e0a81f92d6 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -285,6 +286,16 @@ static bool vm_notify(struct virtqueue *vq)
        return true;
 }
 
+static bool vm_notify_with_data(struct virtqueue *vq)
+{
+       struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
+       u32 data = vring_notification_data(vq);
+
+       writel(data, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY);
+
+       return true;
+}
+
 /* Notify all virtqueues on an interrupt. */
 static irqreturn_t vm_interrupt(int irq, void *opaque)
 {
@@ -360,15 +371,21 @@ static void vm_synchronize_cbs(struct virtio_device *vdev)
 
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int index,
                                  void (*callback)(struct virtqueue *vq),
-                                 const char *name, u32 size, bool ctx)
+                                 const char *name, bool ctx)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+       bool (*notify)(struct virtqueue *vq);
        struct virtio_mmio_vq_info *info;
        struct virtqueue *vq;
        unsigned long flags;
        unsigned int num;
        int err;
 
+       if (__virtio_test_bit(vdev, VIRTIO_F_NOTIFICATION_DATA))
+               notify = vm_notify_with_data;
+       else
+               notify = vm_notify;
+
        if (!name)
                return NULL;
 
@@ -395,12 +412,9 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
                goto error_new_virtqueue;
        }
 
-       if (!size || size > num)
-               size = num;
-
        /* Create the vring */
-       vq = vring_create_virtqueue(index, size, VIRTIO_MMIO_VRING_ALIGN, vdev,
-                                true, true, ctx, vm_notify, callback, name);
+       vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
+                                true, true, ctx, notify, callback, name);
        if (!vq) {
                err = -ENOMEM;
                goto error_new_virtqueue;
@@ -477,7 +491,6 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                       struct virtqueue *vqs[],
                       vq_callback_t *callbacks[],
                       const char * const names[],
-                      u32 sizes[],
                       const bool *ctx,
                       struct irq_affinity *desc)
 {
@@ -503,7 +516,6 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                }
 
                vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-                                    sizes ? sizes[i] : 0,
                                     ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        vm_del_vqs(vdev);