- transition from "ioctl" interface Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> --- .../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