diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:19 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:40:41 +1000 |
commit | 5ffeb84b8eba71b4f88af6997db843ddf68149e0 (patch) | |
tree | b4f6ab43516ef618da892ac8a3a70f948d554218 /drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c | |
parent | 218f978d43296a9ac142a63361e25f517df3d318 (diff) |
drm/nouveau/pm: convert user classes to new-style nvkm_object
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c | 225 |
1 files changed, 119 insertions, 106 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index 90a7d89cc019..5b4ab63809be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -25,7 +25,6 @@ #include <core/client.h> #include <core/option.h> -#include <core/parent.h> #include <nvif/class.h> #include <nvif/ioctl.h> @@ -304,11 +303,11 @@ nvkm_perfdom_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) return -EINVAL; } -static void -nvkm_perfdom_dtor(struct nvkm_object *object) +static void * +nvkm_perfdom_dtor(struct nvkm_object *base) { - struct nvkm_pm *pm = (void *)object->engine; - struct nvkm_perfdom *dom = (void *)object; + struct nvkm_perfdom *dom = nvkm_perfdom(base); + struct nvkm_pm *pm = dom->perfmon->pm; int i; for (i = 0; i < 4; i++) { @@ -320,7 +319,8 @@ nvkm_perfdom_dtor(struct nvkm_object *object) } kfree(ctr); } - nvkm_object_destroy(&dom->base); + + return dom; } static int @@ -353,15 +353,22 @@ nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot, u8 domain, return 0; } +static const struct nvkm_object_func +nvkm_perfdom = { + .dtor = nvkm_perfdom_dtor, + .mthd = nvkm_perfdom_mthd, +}; + static int -nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, +nvkm_perfdom_new_(struct nvkm_perfmon *perfmon, + const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nvif_perfdom_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)engine; + struct nvkm_pm *pm = perfmon->pm; + struct nvkm_object *parent = oclass->parent; struct nvkm_perfdom *sdom = NULL; struct nvkm_perfctr *ctr[4] = {}; struct nvkm_perfdom *dom; @@ -403,10 +410,11 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (!sdom) return -EINVAL; - ret = nvkm_object_create(parent, engine, oclass, 0, &dom); - *pobject = nv_object(dom); - if (ret) - return ret; + if (!(dom = kzalloc(sizeof(*dom), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_perfdom, oclass, &dom->object); + dom->perfmon = perfmon; + *pobject = &dom->object; dom->func = sdom->func; dom->addr = sdom->addr; @@ -416,25 +424,18 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, return 0; } -static struct nvkm_ofuncs -nvkm_perfdom_ofuncs = { - .ctor = nvkm_perfdom_ctor, - .dtor = nvkm_perfdom_dtor, - .init = _nvkm_object_init, - .fini = _nvkm_object_fini, - .mthd = nvkm_perfdom_mthd, -}; - /******************************************************************************* * Perfmon object classes ******************************************************************************/ static int -nvkm_perfmon_mthd_query_domain(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_domain(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_domain_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; struct nvkm_perfdom *dom; u8 domain_nr; int di, ret; @@ -475,13 +476,15 @@ nvkm_perfmon_mthd_query_domain(struct nvkm_object *object, void *data, u32 size) } static int -nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_signal(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_signal_v0 v0; } *args = data; - struct nvkm_device *device = nv_device(object); - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; + struct nvkm_device *device = pm->engine.subdev.device; struct nvkm_perfdom *dom; struct nvkm_perfsig *sig; const bool all = nvkm_boolopt(device->cfgopt, "NvPmShowAll", false); @@ -527,12 +530,14 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size) } static int -nvkm_perfmon_mthd_query_source(struct nvkm_object *object, void *data, u32 size) +nvkm_perfmon_mthd_query_source(struct nvkm_perfmon *perfmon, + void *data, u32 size) { union { struct nvif_perfmon_query_source_v0 v0; } *args = data; - struct nvkm_pm *pm = (void *)object->engine; + struct nvkm_object *object = &perfmon->object; + struct nvkm_pm *pm = perfmon->pm; struct nvkm_perfdom *dom = NULL; struct nvkm_perfsig *sig; struct nvkm_perfsrc *src; @@ -579,117 +584,118 @@ nvkm_perfmon_mthd_query_source(struct nvkm_object *object, void *data, u32 size) static int nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { + struct nvkm_perfmon *perfmon = nvkm_perfmon(object); switch (mthd) { case NVIF_PERFMON_V0_QUERY_DOMAIN: - return nvkm_perfmon_mthd_query_domain(object, data, size); + return nvkm_perfmon_mthd_query_domain(perfmon, data, size); case NVIF_PERFMON_V0_QUERY_SIGNAL: - return nvkm_perfmon_mthd_query_signal(object, data, size); + return nvkm_perfmon_mthd_query_signal(perfmon, data, size); case NVIF_PERFMON_V0_QUERY_SOURCE: - return nvkm_perfmon_mthd_query_source(object, data, size); + return nvkm_perfmon_mthd_query_source(perfmon, data, size); default: break; } return -EINVAL; } -static struct nvkm_oclass -nvkm_perfmon_sclass[] = { - { .handle = NVIF_IOCTL_NEW_V0_PERFDOM, - .ofuncs = &nvkm_perfdom_ofuncs, - }, - {} -}; +static int +nvkm_perfmon_child_new(const struct nvkm_oclass *oclass, void *data, u32 size, + struct nvkm_object **pobject) +{ + struct nvkm_perfmon *perfmon = nvkm_perfmon(oclass->parent); + return nvkm_perfdom_new_(perfmon, oclass, data, size, pobject); +} static int -nvkm_perfmon_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nvkm_perfmon_child_get(struct nvkm_object *base, int index, + struct nvkm_oclass *oclass) { - struct nvkm_parent *perfmon; - int ret = nvkm_parent_create(parent, engine, oclass, 0, - nvkm_perfmon_sclass, 0, &perfmon); - *pobject = perfmon ? &perfmon->object : NULL; - return ret; + if (index == 0) { + oclass->base.oclass = NVIF_IOCTL_NEW_V0_PERFDOM; + oclass->base.minver = 0; + oclass->base.maxver = 0; + oclass->ctor = nvkm_perfmon_child_new; + return 0; + } + return -EINVAL; } -static struct nvkm_ofuncs -nvkm_perfmon_ofuncs = { - .ctor = nvkm_perfmon_ctor, - .dtor = _nvkm_parent_dtor, - .init = _nvkm_parent_init, - .fini = _nvkm_parent_fini, - .mthd = nvkm_perfmon_mthd, -}; +static void * +nvkm_perfmon_dtor(struct nvkm_object *base) +{ + struct nvkm_perfmon *perfmon = nvkm_perfmon(base); + struct nvkm_pm *pm = perfmon->pm; + mutex_lock(&pm->engine.subdev.mutex); + if (pm->perfmon == &perfmon->object) + pm->perfmon = NULL; + mutex_unlock(&pm->engine.subdev.mutex); + return perfmon; +} -struct nvkm_oclass -nvkm_pm_sclass[] = { - { - .handle = NVIF_IOCTL_NEW_V0_PERFMON, - .ofuncs = &nvkm_perfmon_ofuncs, - }, - {}, +static struct nvkm_object_func +nvkm_perfmon = { + .dtor = nvkm_perfmon_dtor, + .mthd = nvkm_perfmon_mthd, + .sclass = nvkm_perfmon_child_get, }; -/******************************************************************************* - * PPM context - ******************************************************************************/ -static void -nvkm_perfctx_dtor(struct nvkm_object *object) +static int +nvkm_perfmon_new(struct nvkm_pm *pm, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) { - struct nvkm_pm *pm = (void *)object->engine; - struct nvkm_perfctx *ctx = (void *)object; + struct nvkm_perfmon *perfmon; - nvkm_gpuobj_destroy(&ctx->base); - mutex_lock(&nv_subdev(pm)->mutex); - if (pm->context == ctx) - pm->context = NULL; - mutex_unlock(&nv_subdev(pm)->mutex); + if (!(perfmon = kzalloc(sizeof(*perfmon), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_perfmon, oclass, &perfmon->object); + perfmon->pm = pm; + *pobject = &perfmon->object; + return 0; } +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + static int -nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nvkm_pm_oclass_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) { - struct nvkm_pm *pm = (void *)engine; - struct nvkm_perfctx *ctx; + struct nvkm_pm *pm = nvkm_pm(oclass->engine); int ret; - /* no context needed for perfdom objects... */ - if (parent->parent != &nvkm_client(parent)->object) { - atomic_inc(&parent->refcount); - *pobject = parent; - return 1; - } - - ret = nvkm_gpuobj_create(parent, engine, oclass, 0, NULL, 0, 0, 0, &ctx); - *pobject = nv_object(ctx); + ret = nvkm_perfmon_new(pm, oclass, data, size, pobject); if (ret) return ret; - mutex_lock(&nv_subdev(pm)->mutex); - if (pm->context == NULL) - pm->context = ctx; - if (ctx != pm->context) - ret = -EBUSY; - mutex_unlock(&nv_subdev(pm)->mutex); - + mutex_lock(&pm->engine.subdev.mutex); + if (pm->perfmon == NULL) + pm->perfmon = *pobject; + ret = (pm->perfmon == *pobject) ? 0 : -EBUSY; + mutex_unlock(&pm->engine.subdev.mutex); return ret; } -struct nvkm_oclass -nvkm_pm_cclass = { - .ofuncs = &(struct nvkm_ofuncs) { - .ctor = nvkm_perfctx_ctor, - .dtor = nvkm_perfctx_dtor, - .init = _nvkm_gpuobj_init, - .fini = _nvkm_gpuobj_fini, - }, +static const struct nvkm_device_oclass +nvkm_pm_oclass = { + .base.oclass = NVIF_IOCTL_NEW_V0_PERFMON, + .base.minver = -1, + .base.maxver = -1, + .ctor = nvkm_pm_oclass_new, }; -/******************************************************************************* - * PPM engine/subdev functions - ******************************************************************************/ +static int +nvkm_pm_oclass_get(struct nvkm_oclass *oclass, int index, + const struct nvkm_device_oclass **class) +{ + if (index == 0) { + oclass->base = nvkm_pm_oclass.base; + *class = &nvkm_pm_oclass; + return index; + } + return 1; +} + int nvkm_perfsrc_new(struct nvkm_pm *pm, struct nvkm_perfsig *sig, const struct nvkm_specsrc *spec) @@ -845,6 +851,11 @@ _nvkm_pm_dtor(struct nvkm_object *object) nvkm_engine_destroy(&pm->engine); } +static const struct nvkm_engine_func +nvkm_pm = { + .base.sclass = nvkm_pm_oclass_get, +}; + int nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, int length, void **pobject) @@ -858,6 +869,8 @@ nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; + pm->engine.func = &nvkm_pm; + INIT_LIST_HEAD(&pm->domains); INIT_LIST_HEAD(&pm->sources); return 0; |