[PATCH 063/156] drm/nouveau/nvif: rework client "new device" api

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:38:29 UTC 2024


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/device.h |  4 +-
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 11 ++++
 .../drm/nouveau/include/nvkm/core/device.h    |  2 -
 drivers/gpu/drm/nouveau/nvif/device.c         | 24 +++++++--
 drivers/gpu/drm/nouveau/nvkm/core/client.c    | 42 ++++++---------
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 52 ++++++++++++++-----
 drivers/gpu/drm/nouveau/nvkm/device/user.h    |  9 ++++
 7 files changed, 99 insertions(+), 45 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/device/user.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h
index fec76f4733a4..c0f8920f0e08 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/device.h
@@ -1,12 +1,14 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVIF_DEVICE_H__
 #define __NVIF_DEVICE_H__
-
 #include <nvif/object.h>
 #include <nvif/cl0080.h>
+#include <nvif/driverif.h>
 #include <nvif/user.h>
 
 struct nvif_device {
+	const struct nvif_device_impl *impl;
+	struct nvif_device_priv *priv;
 	struct nvif_object object;
 	struct nv_device_info_v0 info;
 
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index a6f95c8475b1..8f56798d6509 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -2,6 +2,7 @@
 #ifndef __NVIF_DRIVERIF_H__
 #define __NVIF_DRIVERIF_H__
 struct nvif_client_priv;
+struct nvif_device_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -12,6 +13,10 @@ struct nvif_driver {
 	void (*unmap)(struct nvif_client_priv *, void __iomem *ptr, u32 size);
 };
 
+struct nvif_device_impl {
+	void (*del)(struct nvif_device_priv *);
+};
+
 struct nvif_client_impl {
 	void (*del)(struct nvif_client_priv *);
 
@@ -20,5 +25,11 @@ struct nvif_client_impl {
 			   const struct nvif_client_impl **, struct nvif_client_priv **,
 			   u64 handle);
 	} client;
+
+	struct {
+		int (*new)(struct nvif_client_priv *,
+			   const struct nvif_device_impl **, struct nvif_device_priv **,
+			   u64 handle);
+	} device;
 };
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index efe1a0048328..fff0d7dd0e1b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -129,8 +129,6 @@ struct nvkm_device_oclass {
 	struct nvkm_sclass base;
 };
 
-extern const struct nvkm_sclass nvkm_udevice_sclass;
-
 /* device logging */
 #define nvdev_printk_(d,l,p,f,a...) do {                                       \
 	const struct nvkm_device *_device = (d);                               \
diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c
index 24880931039f..bb95e80f1c81 100644
--- a/drivers/gpu/drm/nouveau/nvif/device.c
+++ b/drivers/gpu/drm/nouveau/nvif/device.c
@@ -23,6 +23,7 @@
  */
 #include <nvif/device.h>
 #include <nvif/client.h>
+#include <nvif/printf.h>
 
 u64
 nvif_device_time(struct nvif_device *device)
@@ -47,23 +48,40 @@ nvif_device_map(struct nvif_device *device)
 void
 nvif_device_dtor(struct nvif_device *device)
 {
+	if (!device->impl)
+		return;
+
 	nvif_user_dtor(device);
 	kfree(device->runlist);
 	device->runlist = NULL;
-	nvif_object_dtor(&device->object);
+
+	device->impl->del(device->priv);
+	device->impl = NULL;
 }
 
 int
 nvif_device_ctor(struct nvif_client *client, const char *name, struct nvif_device *device)
 {
-	int ret = nvif_object_ctor(&client->object, name ? name : "nvifDevice", 0,
-				   0x0080, NULL, 0, &device->object);
+	int ret;
+
 	device->runlist = NULL;
 	device->user.func = NULL;
+
+	ret = client->impl->device.new(client->priv, &device->impl, &device->priv,
+				       nvif_handle(&device->object));
+	NVIF_ERRON(ret, &client->object, "[NEW device]");
+	if (ret)
+		return ret;
+
+	nvif_object_ctor(&client->object, name ?: "nvifDevice", 0, 0, &device->object);
+	device->object.client = client;
+	device->object.priv = device->priv; /*FIXME: used by nvxx_device() */
+
 	if (ret == 0) {
 		device->info.version = 0;
 		ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO,
 				       &device->info, sizeof(device->info));
 	}
+
 	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c
index b57cc0d5a148..1763e863115c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/client.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c
@@ -24,12 +24,28 @@
 #include <core/client.h>
 #include <core/device.h>
 #include <core/option.h>
+#include <device/user.h>
 
 #include <nvif/class.h>
 #include <nvif/driverif.h>
 #include <nvif/event.h>
 #include <nvif/unpack.h>
 
+static int
+nvkm_client_new_device(struct nvif_client_priv *client,
+		       const struct nvif_device_impl **pimpl, struct nvif_device_priv **ppriv,
+		       u64 handle)
+{
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_udevice_new(client->device, pimpl, ppriv, &object);
+	if (ret)
+		return ret;
+
+	return nvkm_object_link_rb(client, &client->object, handle, object);
+}
+
 static int
 nvkm_client_new_client(struct nvif_client_priv *parent,
 		       const struct nvif_client_impl **pimpl, struct nvif_client_priv **ppriv,
@@ -60,32 +76,9 @@ const struct nvif_client_impl
 nvkm_client_impl = {
 	.del = nvkm_client_del,
 	.client.new = nvkm_client_new_client,
+	.device.new = nvkm_client_new_device,
 };
 
-static int
-nvkm_client_child_new(const struct nvkm_oclass *oclass,
-		      void *data, u32 size, struct nvkm_object **pobject)
-{
-	return oclass->base.ctor(oclass, data, size, pobject);
-}
-
-static int
-nvkm_client_child_get(struct nvkm_object *object, int index,
-		      struct nvkm_oclass *oclass)
-{
-	const struct nvkm_sclass *sclass;
-
-	switch (index) {
-	case 0: sclass = &nvkm_udevice_sclass; break;
-	default:
-		return -EINVAL;
-	}
-
-	oclass->ctor = nvkm_client_child_new;
-	oclass->base = *sclass;
-	return 0;
-}
-
 static void *
 nvkm_client_dtor(struct nvkm_object *object)
 {
@@ -95,7 +88,6 @@ nvkm_client_dtor(struct nvkm_object *object)
 static const struct nvkm_object_func
 nvkm_client = {
 	.dtor = nvkm_client_dtor,
-	.sclass = nvkm_client_child_get,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index b30b2e1c590a..a46d448dc244 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -21,6 +21,7 @@
  *
  * Authors: Ben Skeggs
  */
+#include "user.h"
 #include "priv.h"
 #include "ctrl.h"
 
@@ -38,6 +39,8 @@
 struct nvif_device_priv {
 	struct nvkm_object object;
 	struct nvkm_device *device;
+
+	struct nvif_device_impl impl;
 };
 
 static int
@@ -187,6 +190,20 @@ nvkm_udevice_time(struct nvkm_udevice *udev, void *data, u32 size)
 	return ret;
 }
 
+static void
+nvkm_udevice_del(struct nvif_device_priv *udev)
+{
+	struct nvkm_object *object = &udev->object;
+
+	nvkm_object_fini(object, false);
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_device_impl
+nvkm_udevice_impl = {
+	.del = nvkm_udevice_del,
+};
+
 static int
 nvkm_udevice_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
@@ -318,26 +335,33 @@ nvkm_udevice = {
 	.sclass = nvkm_udevice_child_get,
 };
 
-static int
-nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size,
+int
+nvkm_udevice_new(struct nvkm_device *device,
+		 const struct nvif_device_impl **pimpl, struct nvif_device_priv **ppriv,
 		 struct nvkm_object **pobject)
 {
-	struct nvkm_client *client = oclass->client;
 	struct nvif_device_priv *udev;
+	int ret;
 
 	if (!(udev = kzalloc(sizeof(*udev), GFP_KERNEL)))
 		return -ENOMEM;
-	nvkm_object_ctor(&nvkm_udevice, oclass, &udev->object);
+
+	nvkm_object_ctor(&nvkm_udevice, &(struct nvkm_oclass) {}, &udev->object);
+	udev->device = device;
+
+	ret = nvkm_udevice_init(&udev->object);
+	if (ret)
+		goto done;
+
+	udev->impl = nvkm_udevice_impl;
+
+	*pimpl = &udev->impl;
+	*ppriv = udev;
 	*pobject = &udev->object;
 
-	udev->device = client->device;
-	return 0;
-}
+done:
+	if (ret)
+		nvkm_udevice_del(udev);
 
-const struct nvkm_sclass
-nvkm_udevice_sclass = {
-	.oclass = NV_DEVICE,
-	.minver = 0,
-	.maxver = 0,
-	.ctor = nvkm_udevice_new,
-};
+	return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.h b/drivers/gpu/drm/nouveau/nvkm/device/user.h
new file mode 100644
index 000000000000..fb3f94a58960
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_DEVICE_USER_H__
+#define __NVKM_DEVICE_USER_H__
+#include <core/device.h>
+#include <nvif/driverif.h>
+
+int nvkm_udevice_new(struct nvkm_device *, const struct nvif_device_impl **,
+		     struct nvif_device_priv **, struct nvkm_object **);
+#endif
-- 
2.41.0



More information about the Nouveau mailing list