diff mbox series

[05/21] drm/nouveau/nvif: add nvif_driver_func for nvkm->drm callbacks

Message ID 20240613170046.88687-6-bskeggs@nvidia.com (mailing list archive)
State New
Headers show
Series drm/nouveau: insert auxiliary device between nvkm and drm | expand

Commit Message

Ben Skeggs June 13, 2024, 4:59 p.m. UTC
A later patch in this series will move the code that binds to a PCI/
Tegra device into NVKM, and requires a couple of callbacks to handle
switcheroo, etc.

nvif_event is generally used for NVKM->DRM callbacks, but these will
need to be registered before nvif_event is ready.

This patch replaces the event() function pointer that was passed to
nvkm_driver_ctor() during init with a nvif_driver_func struct, that
contains the existing event() callback.

Signed-off-by: Ben Skeggs <bskeggs@nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/driverif.h    |  4 ++++
 drivers/gpu/drm/nouveau/include/nvif/event.h       |  2 ++
 drivers/gpu/drm/nouveau/include/nvkm/core/client.h |  3 +--
 drivers/gpu/drm/nouveau/include/nvkm/core/device.h |  2 ++
 drivers/gpu/drm/nouveau/nouveau_drm.c              |  7 +++++++
 drivers/gpu/drm/nouveau/nouveau_drv.h              |  1 +
 drivers/gpu/drm/nouveau/nvif/event.c               |  9 +++++++++
 drivers/gpu/drm/nouveau/nvkm/core/client.c         | 13 +++++++++----
 drivers/gpu/drm/nouveau/nvkm/core/driver.c         | 14 +-------------
 9 files changed, 36 insertions(+), 19 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 0476dd6621b5..638c72c1b580 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -34,6 +34,10 @@  struct nvif_event_impl {
 	int (*block)(struct nvif_event_priv *);
 };
 
+struct nvif_driver_func {
+	enum nvif_event_stat (*event)(u64 token, void *repv, u32 repc);
+};
+
 struct nvif_driver {
 	const char *name;
 	int (*suspend)(struct nvif_client_priv *);
diff --git a/drivers/gpu/drm/nouveau/include/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h
index 6c52de0e17d0..ce14e478b1fe 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/event.h
@@ -5,6 +5,8 @@ 
 #include <nvif/driverif.h>
 struct nvif_event;
 
+enum nvif_event_stat nvif_event(u64 token, void *repv, u32 repc);
+
 typedef enum nvif_event_stat (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc);
 
 struct nvif_event {
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
index 5c9a54d4bd64..4e5d56056b81 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
@@ -14,10 +14,9 @@  struct nvkm_client {
 	spinlock_t obj_lock;
 
 	void *data;
-	int (*event)(u64 token, void *argv, u32 argc);
 };
 
-int nvkm_client_new(const char *name, struct nvkm_device *, int (*event)(u64, void *, u32),
+int nvkm_client_new(const char *name, struct nvkm_device *,
 		    const struct nvif_client_impl **, struct nvif_client_priv **);
 int nvkm_client_event(struct nvkm_client *client, u64 token, void *repv, u32 repc);
 
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index fff0d7dd0e1b..c9965934b0d5 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -71,6 +71,8 @@  struct nvkm_device {
 		bool armed;
 		bool legacy_done;
 	} intr;
+
+	const struct nvif_driver_func *driver;
 };
 
 struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 18990d21dc48..09947790f677 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -614,6 +614,11 @@  nouveau_drm_device_init(struct nouveau_drm *drm)
 	return ret;
 }
 
+static const struct nvif_driver_func
+nouveau_driver = {
+	.event = nvif_event,
+};
+
 static void
 nouveau_drm_device_del(struct nouveau_drm *drm)
 {
@@ -643,9 +648,11 @@  nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren
 		return ERR_PTR(-ENOMEM);
 
 	drm->nvkm = device;
+	drm->driver = nouveau_driver;
 
 	device->cfgopt = nouveau_config;
 	device->dbgopt = nouveau_debug;
+	device->driver = &drm->driver;
 
 	nvif_parent_ctor(&nouveau_parent, &drm->parent);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 832651fe9f42..52589d5eab63 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -202,6 +202,7 @@  u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size)
 
 struct nouveau_drm {
 	struct nvkm_device *nvkm;
+	struct nvif_driver_func driver;
 	struct nvif_parent parent;
 	struct nvif_client client;
 	struct nvif_device device;
diff --git a/drivers/gpu/drm/nouveau/nvif/event.c b/drivers/gpu/drm/nouveau/nvif/event.c
index 2974ec8e13af..816e3d1bedb4 100644
--- a/drivers/gpu/drm/nouveau/nvif/event.c
+++ b/drivers/gpu/drm/nouveau/nvif/event.c
@@ -23,6 +23,15 @@ 
 #include <nvif/driverif.h>
 #include <nvif/printf.h>
 
+enum nvif_event_stat
+nvif_event(u64 token, void *repv, u32 repc)
+{
+	struct nvif_object *object = (void *)(unsigned long)token;
+	struct nvif_event *event = container_of(object, typeof(*event), object);
+
+	return event->func(event, repv, repc);
+}
+
 int
 nvif_event_block(struct nvif_event *event)
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c
index beb966d65daf..b767d77ad205 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/client.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c
@@ -23,6 +23,7 @@ 
  */
 #include <core/client.h>
 #include <core/device.h>
+#include <core/event.h>
 #include <core/option.h>
 #include <device/user.h>
 
@@ -34,7 +35,12 @@ 
 int
 nvkm_client_event(struct nvkm_client *client, u64 token, void *repv, u32 repc)
 {
-	return client->event(token, repv, repc);
+	enum nvif_event_stat stat = client->device->driver->event(token, repv, repc);
+
+	if (stat == NVIF_EVENT_KEEP)
+		return NVKM_EVENT_KEEP;
+
+	return NVKM_EVENT_DROP;
 }
 
 static int
@@ -59,7 +65,7 @@  nvkm_client_new_client(struct nvif_client_priv *parent,
 	struct nvkm_client *client;
 	int ret;
 
-	ret = nvkm_client_new("client", parent->device, parent->event, pimpl, &client);
+	ret = nvkm_client_new("client", parent->device, pimpl, &client);
 	if (ret)
 		return ret;
 
@@ -96,7 +102,7 @@  nvkm_client = {
 };
 
 int
-nvkm_client_new(const char *name, struct nvkm_device *device, int (*event)(u64, void *, u32),
+nvkm_client_new(const char *name, struct nvkm_device *device,
 		const struct nvif_client_impl **pimpl, struct nvif_client_priv **ppriv)
 {
 	struct nvkm_oclass oclass = {};
@@ -112,7 +118,6 @@  nvkm_client_new(const char *name, struct nvkm_device *device, int (*event)(u64,
 	client->device = device;
 	client->debug = NV_DBG_ERROR;
 	spin_lock_init(&client->obj_lock);
-	client->event = event;
 
 	*pimpl = &nvkm_client_impl;
 	*ppriv = client;
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/driver.c b/drivers/gpu/drm/nouveau/nvkm/core/driver.c
index 86ada3c888ec..dcc5dc7f246e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/driver.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/driver.c
@@ -56,18 +56,6 @@  nvkm_driver_suspend(struct nvif_client_priv *client)
 	return nvkm_object_fini(&client->object, true);
 }
 
-static int
-nvkm_driver_event(u64 token, void *repv, u32 repc)
-{
-	struct nvif_object *object = (void *)(unsigned long)token;
-	struct nvif_event *event = container_of(object, typeof(*event), object);
-
-	if (event->func(event, repv, repc) == NVIF_EVENT_KEEP)
-		return NVKM_EVENT_KEEP;
-
-	return NVKM_EVENT_DROP;
-}
-
 static const struct nvif_driver
 nvkm_driver = {
 	.name = "nvkm",
@@ -83,7 +71,7 @@  nvkm_driver_ctor(struct nvkm_device *device, const struct nvif_driver **pdrv,
 {
 	int ret;
 
-	ret = nvkm_client_new("driver", device, nvkm_driver_event, pimpl, ppriv);
+	ret = nvkm_client_new("driver", device, pimpl, ppriv);
 	if (ret)
 		return ret;