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@xxxxxxxxxx> --- 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