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 <bske...@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 --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;
 
-- 
2.44.0

Reply via email to