@@ -304,6 +304,59 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)
put_device(cdev_dev(idxd_cdev));
}
+static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
+{
+ struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
+ struct idxd_device *idxd = wq->idxd;
+ int rc;
+
+ if (idxd->state != IDXD_DEV_ENABLED)
+ return -ENXIO;
+
+ mutex_lock(&wq->wq_lock);
+ wq->type = IDXD_WQT_USER;
+ rc = __drv_enable_wq(wq);
+ if (rc < 0)
+ goto err;
+
+ rc = idxd_wq_add_cdev(wq);
+ if (rc < 0)
+ goto err_cdev;
+
+ mutex_unlock(&wq->wq_lock);
+ return 0;
+
+err_cdev:
+ __drv_disable_wq(wq);
+err:
+ wq->type = IDXD_WQT_NONE;
+ mutex_unlock(&wq->wq_lock);
+ return rc;
+}
+
+static void idxd_user_drv_remove(struct idxd_dev *idxd_dev)
+{
+ struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
+
+ mutex_lock(&wq->wq_lock);
+ idxd_wq_del_cdev(wq);
+ __drv_disable_wq(wq);
+ wq->type = IDXD_WQT_NONE;
+ mutex_unlock(&wq->wq_lock);
+}
+
+static enum idxd_dev_type dev_types[] = {
+ IDXD_DEV_WQ,
+ IDXD_DEV_NONE,
+};
+
+struct idxd_device_driver idxd_user_drv = {
+ .probe = idxd_user_drv_probe,
+ .remove = idxd_user_drv_remove,
+ .name = "user",
+ .type = dev_types,
+};
+
int idxd_cdev_register(void)
{
int rc, i;
@@ -1201,19 +1201,8 @@ int __drv_enable_wq(struct idxd_wq *wq)
}
wq->client_count = 0;
-
- if (is_idxd_wq_cdev(wq)) {
- rc = idxd_wq_add_cdev(wq);
- if (rc < 0) {
- dev_dbg(dev, "wq %d cdev creation failed\n", wq->id);
- goto err_client;
- }
- }
-
return 0;
-err_client:
- idxd_wq_unmap_portal(wq);
err_map_portal:
rc = idxd_wq_disable(wq, false);
if (rc < 0)
@@ -1239,9 +1228,6 @@ void __drv_disable_wq(struct idxd_wq *wq)
lockdep_assert_held(&wq->wq_lock);
- if (is_idxd_wq_cdev(wq))
- idxd_wq_del_cdev(wq);
-
if (idxd_wq_refcount(wq))
dev_warn(dev, "Clients has claim on wq %d: %d\n",
wq->id, idxd_wq_refcount(wq));
@@ -60,6 +60,7 @@ struct idxd_device_driver {
extern struct idxd_device_driver dsa_drv;
extern struct idxd_device_driver idxd_drv;
extern struct idxd_device_driver idxd_dmaengine_drv;
+extern struct idxd_device_driver idxd_user_drv;
struct idxd_irq_entry {
struct idxd_device *idxd;
@@ -840,6 +840,10 @@ static int __init idxd_init_module(void)
if (err < 0)
goto err_idxd_dmaengine_driver_register;
+ err = idxd_driver_register(&idxd_user_drv);
+ if (err < 0)
+ goto err_idxd_user_driver_register;
+
err = idxd_driver_register(&dsa_drv);
if (err < 0)
goto err_dsa_driver_register;
@@ -859,6 +863,8 @@ static int __init idxd_init_module(void)
err_cdev_register:
idxd_driver_unregister(&dsa_drv);
err_dsa_driver_register:
+ idxd_driver_unregister(&idxd_user_drv);
+err_idxd_user_driver_register:
idxd_driver_unregister(&idxd_dmaengine_drv);
err_idxd_dmaengine_driver_register:
idxd_driver_unregister(&idxd_drv);
@@ -870,6 +876,7 @@ module_init(idxd_init_module);
static void __exit idxd_exit_module(void)
{
+ idxd_driver_unregister(&idxd_user_drv);
idxd_driver_unregister(&idxd_dmaengine_drv);
idxd_driver_unregister(&idxd_drv);
idxd_driver_unregister(&dsa_drv);