summaryrefslogtreecommitdiff
path: root/drivers/vfio/mdev
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vfio/mdev')
-rw-r--r--drivers/vfio/mdev/mdev_core.c30
-rw-r--r--drivers/vfio/mdev/mdev_driver.c10
2 files changed, 32 insertions, 8 deletions
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index ff8c1a845166..e4581ec093a6 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -94,9 +94,11 @@ static void mdev_device_remove_common(struct mdev_device *mdev)
mdev_remove_sysfs_files(mdev);
device_del(&mdev->dev);
lockdep_assert_held(&parent->unreg_sem);
- ret = parent->ops->remove(mdev);
- if (ret)
- dev_err(&mdev->dev, "Remove failed: err=%d\n", ret);
+ if (parent->ops->remove) {
+ ret = parent->ops->remove(mdev);
+ if (ret)
+ dev_err(&mdev->dev, "Remove failed: err=%d\n", ret);
+ }
/* Balances with device_initialize() */
put_device(&mdev->dev);
@@ -127,7 +129,9 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
char *envp[] = { env_string, NULL };
/* check for mandatory ops */
- if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups)
+ if (!ops || !ops->supported_type_groups)
+ return -EINVAL;
+ if (!ops->device_driver && (!ops->create || !ops->remove))
return -EINVAL;
dev = get_device(dev);
@@ -256,6 +260,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
int ret;
struct mdev_device *mdev, *tmp;
struct mdev_parent *parent = type->parent;
+ struct mdev_driver *drv = parent->ops->device_driver;
mutex_lock(&mdev_list_lock);
@@ -296,14 +301,22 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
goto out_put_device;
}
- ret = parent->ops->create(mdev);
- if (ret)
- goto out_unlock;
+ if (parent->ops->create) {
+ ret = parent->ops->create(mdev);
+ if (ret)
+ goto out_unlock;
+ }
ret = device_add(&mdev->dev);
if (ret)
goto out_remove;
+ if (!drv)
+ drv = &vfio_mdev_driver;
+ ret = device_driver_attach(&drv->driver, &mdev->dev);
+ if (ret)
+ goto out_del;
+
ret = mdev_create_sysfs_files(mdev);
if (ret)
goto out_del;
@@ -317,7 +330,8 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
out_del:
device_del(&mdev->dev);
out_remove:
- parent->ops->remove(mdev);
+ if (parent->ops->remove)
+ parent->ops->remove(mdev);
out_unlock:
up_read(&parent->unreg_sem);
out_put_device:
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 041699571b7e..c368ec824e2b 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -71,10 +71,20 @@ static int mdev_remove(struct device *dev)
return 0;
}
+static int mdev_match(struct device *dev, struct device_driver *drv)
+{
+ /*
+ * No drivers automatically match. Drivers are only bound by explicit
+ * device_driver_attach()
+ */
+ return 0;
+}
+
struct bus_type mdev_bus_type = {
.name = "mdev",
.probe = mdev_probe,
.remove = mdev_remove,
+ .match = mdev_match,
};
EXPORT_SYMBOL_GPL(mdev_bus_type);