- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bske...@nvidia.com>
---
 .../gpu/drm/nouveau/include/nvif/driverif.h   |  8 +++++
 drivers/gpu/drm/nouveau/include/nvif/user.h   |  5 +++-
 drivers/gpu/drm/nouveau/nouveau_dma.c         |  2 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c         |  2 +-
 drivers/gpu/drm/nouveau/nvif/user.c           | 16 ++++++----
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 19 ++++++++++--
 .../gpu/drm/nouveau/nvkm/subdev/vfn/base.c    |  1 -
 .../gpu/drm/nouveau/nvkm/subdev/vfn/priv.h    |  3 --
 .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c    | 29 +++++++++++++++----
 .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h    |  9 ++++++
 10 files changed, 73 insertions(+), 21 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h 
b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 05d69ea0f002..35a5869eb036 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -4,6 +4,7 @@
 struct nvif_client_priv;
 struct nvif_device_priv;
 struct nvif_control_priv;
+struct nvif_usermode_priv;
 
 struct nvif_driver {
        const char *name;
@@ -69,6 +70,10 @@ struct nvif_control_impl {
        } pstate;
 };
 
+struct nvif_usermode_impl {
+       void (*del)(struct nvif_usermode_priv *);
+};
+
 struct nvif_device_impl {
        void (*del)(struct nvif_device_priv *);
 
@@ -117,6 +122,9 @@ struct nvif_device_impl {
 
        struct {
                s32 oclass;
+               int (*new)(struct nvif_device_priv *,
+                          const struct nvif_usermode_impl **, struct 
nvif_usermode_priv **,
+                          u64 handle);
        } usermode;
 
        struct {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/user.h 
b/drivers/gpu/drm/nouveau/include/nvif/user.h
index 146986a9fe53..51104955c1e3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/user.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/user.h
@@ -4,8 +4,11 @@
 struct nvif_device;
 
 struct nvif_user {
-       const struct nvif_user_func *func;
+       const struct nvif_usermode_impl *impl;
+       struct nvif_usermode_priv *priv;
        struct nvif_object object;
+
+       const struct nvif_user_func *func;
 };
 
 struct nvif_user_func {
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c 
b/drivers/gpu/drm/nouveau/nouveau_dma.c
index a1f329ef0641..83eb9c9fa67e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -72,7 +72,7 @@ void
 nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length,
              bool no_prefetch)
 {
-       struct nvif_user *user = &chan->cli->drm->client.device.user;
+       struct nvif_user *user = &chan->cli->drm->device.user;
        struct nouveau_bo *pb = chan->push.buffer;
        int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 76990dde1b6a..a91ad8e65a0f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -474,7 +474,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
 
        /* Volta requires access to a doorbell register for kickoff. */
        if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_VOLTA) {
-               ret = nvif_user_ctor(device, "drmUsermode");
+               ret = nvif_user_ctor(&drm->device, "drmUsermode");
                if (ret)
                        return;
        }
diff --git a/drivers/gpu/drm/nouveau/nvif/user.c 
b/drivers/gpu/drm/nouveau/nvif/user.c
index d8d37c1c8169..878883aff9c5 100644
--- a/drivers/gpu/drm/nouveau/nvif/user.c
+++ b/drivers/gpu/drm/nouveau/nvif/user.c
@@ -21,6 +21,7 @@
  */
 #include <nvif/user.h>
 #include <nvif/device.h>
+#include <nvif/driverif.h>
 #include <nvif/printf.h>
 
 #include <nvif/class.h>
@@ -28,8 +29,9 @@
 void
 nvif_user_dtor(struct nvif_device *device)
 {
-       if (device->user.func) {
-               nvif_object_dtor(&device->user.object);
+       if (device->user.impl) {
+               device->user.impl->del(device->user.priv);
+               device->user.impl = NULL;
                device->user.func = NULL;
        }
 }
@@ -53,13 +55,15 @@ nvif_user_ctor(struct nvif_device *device, const char *name)
                return -ENODEV;
        }
 
-       ret = nvif_object_ctor(&device->object, name ? name : "nvifUsermode",
-                              0, oclass, NULL, 0,
-                              &device->user.object);
+       ret = device->impl->usermode.new(device->priv, &device->user.impl, 
&device->user.priv,
+                                        nvif_handle(&device->user.object));
+       NVIF_ERRON(ret, &device->object, "[NEW usermode%04x]", oclass);
        if (ret)
                return ret;
 
-       nvif_object_map(&device->user.object, NULL, 0);
+       nvif_object_ctor(&device->object, name ?: "nvifUsermode", 0, oclass, 
&device->user.object);
        device->user.func = func;
+
+       nvif_object_map(&device->user.object, NULL, 0);
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c 
b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index 97d54b812165..aadd0c0956ee 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -29,6 +29,7 @@
 #include <subdev/fb.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
+#include <subdev/vfn/uvfn.h>
 #include <engine/disp/priv.h>
 #include <engine/fifo/ufifo.h>
 
@@ -39,6 +40,20 @@ struct nvif_device_priv {
        struct nvif_device_impl impl;
 };
 
+static int
+nvkm_udevice_usermode_new(struct nvif_device_priv *udev, const struct 
nvif_usermode_impl **pimpl,
+                         struct nvif_usermode_priv **ppriv, u64 handle)
+{
+       struct nvkm_object *object;
+       int ret;
+
+       ret = nvkm_uvfn_new(udev->device, pimpl, ppriv, &object);
+       if (ret)
+               return ret;
+
+       return nvkm_object_link_rb(udev->object.client, &udev->object, handle, 
object);
+}
+
 static int
 nvkm_udevice_control_new(struct nvif_device_priv *udev,
                         const struct nvif_control_impl **pimpl, struct 
nvif_control_priv **ppriv)
@@ -74,6 +89,7 @@ nvkm_udevice_impl = {
        .del = nvkm_udevice_del,
        .time = nvkm_udevice_time,
        .control.new = nvkm_udevice_control_new,
+       .usermode.new = nvkm_udevice_usermode_new,
 };
 
 static int
@@ -154,8 +170,6 @@ nvkm_udevice_child_get(struct nvkm_object *object, int 
index,
                        sclass = &device->mmu->user;
                else if (device->fault && index-- == 0)
                        sclass = &device->fault->user;
-               else if (device->vfn && index-- == 0)
-                       sclass = &device->vfn->user;
                else
                        return -EINVAL;
 
@@ -263,6 +277,7 @@ nvkm_udevice_new(struct nvkm_device *device,
 
        if (device->vfn) {
                udev->impl.usermode.oclass = device->vfn->user.base.oclass;
+               udev->impl.usermode.new = nvkm_udevice_usermode_new;
        }
 
        if (device->mmu) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
index 62e81d551f44..2215de6c4803 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
@@ -54,7 +54,6 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct 
nvkm_device *device,
                        return ret;
        }
 
-       vfn->user.ctor = nvkm_uvfn_new;
        vfn->user.base = func->user.base;
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
index 3a09781ad032..40245777c600 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
@@ -24,7 +24,4 @@ int nvkm_vfn_new_(const struct nvkm_vfn_func *, struct 
nvkm_device *, enum nvkm_
                  u32 addr, struct nvkm_vfn **);
 
 extern const struct nvkm_intr_func tu102_vfn_intr;
-
-int nvkm_uvfn_new(struct nvkm_device *, const struct nvkm_oclass *, void *, 
u32,
-                 struct nvkm_object **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
index fe35024d69ba..6b0ddeb1f568 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
@@ -19,6 +19,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
+#include "uvfn.h"
 #include "priv.h"
 
 #include <core/object.h>
@@ -26,6 +27,8 @@
 struct nvif_usermode_priv {
        struct nvkm_object object;
        struct nvkm_vfn *vfn;
+
+       struct nvif_usermode_impl impl;
 };
 
 static int
@@ -41,26 +44,40 @@ nvkm_uvfn_map(struct nvkm_object *object, void *argv, u32 
argc,
        return 0;
 }
 
+static void
+nvkm_uvfn_del(struct nvif_usermode_priv *uvfn)
+{
+       struct nvkm_object *object = &uvfn->object;
+
+       nvkm_object_del(&object);
+}
+
+static const struct nvif_usermode_impl
+nvkm_uvfn_impl = {
+       .del = nvkm_uvfn_del,
+};
+
 static const struct nvkm_object_func
 nvkm_uvfn = {
        .map = nvkm_uvfn_map,
 };
 
 int
-nvkm_uvfn_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
-             void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_uvfn_new(struct nvkm_device *device, const struct nvif_usermode_impl 
**pimpl,
+             struct nvif_usermode_priv **ppriv, struct nvkm_object **pobject)
 {
        struct nvif_usermode_priv *uvfn;
 
-       if (argc != 0)
-               return -ENOSYS;
-
        if (!(uvfn = kzalloc(sizeof(*uvfn), GFP_KERNEL)))
                return -ENOMEM;
 
-       nvkm_object_ctor(&nvkm_uvfn, oclass, &uvfn->object);
+       nvkm_object_ctor(&nvkm_uvfn, &(struct nvkm_oclass) {}, &uvfn->object);
        uvfn->vfn = device->vfn;
 
+       uvfn->impl = nvkm_uvfn_impl;
+
+       *pimpl = &uvfn->impl;
+       *ppriv = uvfn;
        *pobject = &uvfn->object;
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
new file mode 100644
index 000000000000..23f636eb3b58
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UVFN_H__
+#define __NVKM_UVFN_H__
+#include <subdev/vfn.h>
+#include <nvif/driverif.h>
+
+int nvkm_uvfn_new(struct nvkm_device *, const struct nvif_usermode_impl **,
+                 struct nvif_usermode_priv **, struct nvkm_object **);
+#endif
-- 
2.41.0

Reply via email to