net: mdio-mux-meson-g12a: force internal PHY off on mux switch
[platform/kernel/linux-rpi.git] / drivers / vdpa / vdpa.c
index 3fc4525..8657149 100644 (file)
@@ -69,6 +69,7 @@ static void vdpa_release_dev(struct device *d)
  * @config: the bus operations that is supported by this device
  * @size: size of the parent structure that contains private data
  * @name: name of the vdpa device; optional.
+ * @use_va: indicate whether virtual address must be used by this device
  *
  * Driver should use vdpa_alloc_device() wrapper macro instead of
  * using this directly.
@@ -78,7 +79,8 @@ static void vdpa_release_dev(struct device *d)
  */
 struct vdpa_device *__vdpa_alloc_device(struct device *parent,
                                        const struct vdpa_config_ops *config,
-                                       size_t size, const char *name)
+                                       size_t size, const char *name,
+                                       bool use_va)
 {
        struct vdpa_device *vdev;
        int err = -EINVAL;
@@ -89,6 +91,10 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
        if (!!config->dma_map != !!config->dma_unmap)
                goto err;
 
+       /* It should only work for the device that use on-chip IOMMU */
+       if (use_va && !(config->dma_map || config->set_map))
+               goto err;
+
        err = -ENOMEM;
        vdev = kzalloc(size, GFP_KERNEL);
        if (!vdev)
@@ -104,6 +110,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
        vdev->index = err;
        vdev->config = config;
        vdev->features_valid = false;
+       vdev->use_va = use_va;
 
        if (name)
                err = dev_set_name(&vdev->dev, "%s", name);
@@ -346,7 +353,8 @@ static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *m
                goto msg_err;
 
        while (mdev->id_table[i].device) {
-               supported_classes |= BIT(mdev->id_table[i].device);
+               if (mdev->id_table[i].device <= 63)
+                       supported_classes |= BIT_ULL(mdev->id_table[i].device);
                i++;
        }
 
@@ -550,14 +558,19 @@ static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
                goto mdev_err;
        }
        err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack);
-       if (!err)
-               err = genlmsg_reply(msg, info);
+       if (err)
+               goto mdev_err;
+
+       err = genlmsg_reply(msg, info);
+       put_device(dev);
+       mutex_unlock(&vdpa_dev_mutex);
+       return err;
+
 mdev_err:
        put_device(dev);
 err:
        mutex_unlock(&vdpa_dev_mutex);
-       if (err)
-               nlmsg_free(msg);
+       nlmsg_free(msg);
        return err;
 }