Loading drivers/gpu/drm/nouveau/include/nvkm/core/device.h +48 −2 Original line number Diff line number Diff line Loading @@ -84,9 +84,9 @@ struct nvkm_device { struct nvkm_event event; const char *cname; u64 disable_mask; const struct nvkm_device_chip *chip; enum { NV_04 = 0x04, NV_10 = 0x10, Loading @@ -104,7 +104,6 @@ struct nvkm_device { u32 crystal; struct nvkm_oclass *oclass[NVDEV_SUBDEV_NR]; struct nvkm_object *subdev[NVDEV_SUBDEV_NR]; struct { struct notifier_block nb; Loading Loading @@ -153,6 +152,9 @@ struct nvkm_device { struct nouveau_platform_gpu *gpu; }; struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int index); struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int index); struct nvkm_device_func { struct nvkm_device_pci *(*pci)(struct nvkm_device *); struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); Loading @@ -164,6 +166,50 @@ struct nvkm_device_func { struct nvkm_device_quirk { }; struct nvkm_device_chip { const char *name; int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **); int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **); int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **); int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **); int (*devinit)(struct nvkm_device *, int idx, struct nvkm_devinit **); int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **); int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **); int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **); int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **); int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **); int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **); int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **); int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **); int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **); int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **); int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **); int (*dma )(struct nvkm_device *, int idx, struct nvkm_dmaeng **); int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **); int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **); int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **); int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **); int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **); }; struct nvkm_device *nvkm_device_find(u64 name); int nvkm_device_list(u64 *name, int size); Loading drivers/gpu/drm/nouveau/nvkm/core/engine.c +10 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ static int nvkm_engine_fini(struct nvkm_subdev *obj, bool suspend) { struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev); if (engine->subdev.object.oclass) return engine->subdev.object.oclass->ofuncs->fini(&engine->subdev.object, suspend); if (engine->func->fini) return engine->func->fini(engine, suspend); return 0; Loading @@ -86,6 +88,9 @@ nvkm_engine_init(struct nvkm_subdev *obj) return ret; } if (engine->subdev.object.oclass) return engine->subdev.object.oclass->ofuncs->init(&engine->subdev.object); if (engine->func->oneinit && !engine->subdev.oneinit) { nvkm_trace(subdev, "one-time init running...\n"); time = ktime_to_us(ktime_get()); Loading @@ -110,6 +115,10 @@ static void * nvkm_engine_dtor(struct nvkm_subdev *obj) { struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev); if (engine->subdev.object.oclass) { engine->subdev.object.oclass->ofuncs->dtor(&engine->subdev.object); return NULL; } if (engine->func->dtor) return engine->func->dtor(engine); return engine; Loading Loading @@ -201,5 +210,6 @@ nvkm_engine_create_(struct nvkm_object *parent, struct nvkm_object *engobj, INIT_LIST_HEAD(&engine->contexts); spin_lock_init(&engine->lock); engine->subdev.func = &nvkm_engine_func; return 0; } drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +14 −11 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) struct nvkm_object *engctx = NULL; struct nvkm_object *object = NULL; struct nvkm_parent *parent; struct nvkm_object *engine; struct nvkm_engine *engine; struct nvkm_oclass *oclass; u32 _handle, _oclass; int ret; Loading @@ -117,7 +117,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) parent = nv_parent(handle->object); /* check that parent supports the requested subclass */ ret = nvkm_parent_sclass(&parent->object, _oclass, &engine, &oclass); ret = nvkm_parent_sclass(&parent->object, _oclass, (struct nvkm_object **)&engine, &oclass); if (ret) { nvif_debug(&parent->object, "illegal class 0x%04x\n", _oclass); goto fail_class; Loading @@ -128,18 +129,20 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) * state calculated at init (ie. default context construction) */ if (engine) { ret = nvkm_object_inc(engine); if (ret) engine = nvkm_engine_ref(engine); if (IS_ERR(engine)) { ret = PTR_ERR(engine); engine = NULL; goto fail_class; } } /* if engine requires it, create a context object to insert * between the parent and its children (eg. PGRAPH context) */ if (engine && nv_engine(engine)->cclass) { ret = nvkm_object_old(&parent->object, engine, nv_engine(engine)->cclass, data, size, &engctx); if (engine && engine->cclass) { ret = nvkm_object_old(&parent->object, &engine->subdev.object, engine->cclass, data, size, &engctx); if (ret) goto fail_engctx; } else { Loading @@ -147,7 +150,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) } /* finally, create new object and bind it to its handle */ ret = nvkm_object_old(engctx, engine, oclass, data, size, &object); ret = nvkm_object_old(engctx, &engine->subdev.object, oclass, data, size, &object); client->data = object; if (ret) goto fail_ctor; Loading Loading @@ -178,8 +182,7 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) fail_ctor: nvkm_object_ref(NULL, &engctx); fail_engctx: if (engine) nvkm_object_dec(engine, false); nvkm_engine_unref(&engine); fail_class: return ret; } Loading drivers/gpu/drm/nouveau/nvkm/core/object.c +8 −40 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ nvkm_object_del(struct nvkm_object **pobject) if (object && !WARN_ON(!object->func)) { if (object->func->dtor) *pobject = object->func->dtor(object); nvkm_engine_unref(&object->engine); kfree(*pobject); *pobject = NULL; } Loading @@ -212,7 +213,7 @@ nvkm_object_ctor(const struct nvkm_object_func *func, { object->func = func; object->client = oclass->client; object->engine = oclass->engine; object->engine = nvkm_engine_ref(oclass->engine); object->oclass_name = oclass->base.oclass; object->handle = oclass->handle; object->parent = oclass->parent; Loading Loading @@ -251,10 +252,11 @@ nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size, } int nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engobj, struct nvkm_oclass *oclass, u32 pclass, int size, void **pobject) { struct nvkm_engine *engine = engobj ? nv_engine(engobj) : NULL; struct nvkm_object *object; object = *pobject = kzalloc(size, GFP_KERNEL); Loading @@ -262,7 +264,7 @@ nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine, return -ENOMEM; nvkm_object_ref(parent, &object->parent); nvkm_object_ref(engine, (struct nvkm_object **)&object->engine); object->engine = nvkm_engine_ref(engine); object->oclass = oclass; object->pclass = pclass; atomic_set(&object->refcount, 1); Loading @@ -287,7 +289,7 @@ _nvkm_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine, void nvkm_object_destroy(struct nvkm_object *object) { nvkm_object_ref(NULL, (struct nvkm_object **)&object->engine); nvkm_engine_unref(&object->engine); nvkm_object_ref(NULL, &object->parent); kfree(object); } Loading Loading @@ -333,6 +335,7 @@ nvkm_object_old(struct nvkm_object *parent, struct nvkm_object *engine, } if (ret == 0) { if (!nv_iclass(object, NV_SUBDEV_CLASS)) atomic_set(&object->refcount, 1); } Loading Loading @@ -370,14 +373,6 @@ nvkm_object_inc(struct nvkm_object *object) goto fail_parent; } if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); ret = nvkm_object_inc(&object->engine->subdev.object); mutex_unlock(&nv_subdev(object->engine)->mutex); if (ret) goto fail_engine; } ret = nvkm_object_init(object); atomic_set(&object->usecount, 1); if (ret) Loading @@ -386,12 +381,6 @@ nvkm_object_inc(struct nvkm_object *object) return 0; fail_self: if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_dec(&object->engine->subdev.object, false); mutex_unlock(&nv_subdev(object->engine)->mutex); } fail_engine: if (object->parent) nvkm_object_dec(object->parent, false); fail_parent: Loading @@ -405,12 +394,6 @@ nvkm_object_decf(struct nvkm_object *object) nvkm_object_fini(object, false); atomic_set(&object->usecount, 0); if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_dec(&object->engine->subdev.object, false); mutex_unlock(&nv_subdev(object->engine)->mutex); } if (object->parent) nvkm_object_dec(object->parent, false); Loading @@ -427,14 +410,6 @@ nvkm_object_decs(struct nvkm_object *object) if (ret) return ret; if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); ret = nvkm_object_dec(&object->engine->subdev.object, true); mutex_unlock(&nv_subdev(object->engine)->mutex); if (ret) goto fail_engine; } if (object->parent) { ret = nvkm_object_dec(object->parent, true); if (ret) Loading @@ -444,13 +419,6 @@ nvkm_object_decs(struct nvkm_object *object) return 0; fail_parent: if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_inc(&object->engine->subdev.object); mutex_unlock(&nv_subdev(object->engine)->mutex); } fail_engine: nvkm_object_init(object); return ret; Loading drivers/gpu/drm/nouveau/nvkm/core/subdev.c +34 −5 Original line number Diff line number Diff line Loading @@ -74,6 +74,12 @@ nvkm_subdev_name[64] = { void nvkm_subdev_intr(struct nvkm_subdev *subdev) { if (subdev->object.oclass) { if (subdev->intr) subdev->intr(subdev); return; } if (subdev->func->intr) subdev->func->intr(subdev); } Loading @@ -85,10 +91,18 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) const char *action = suspend ? "suspend" : "fini"; u32 pmc_enable = subdev->pmc_enable; s64 time; int ret; nvkm_trace(subdev, "%s running...\n", action); time = ktime_to_us(ktime_get()); if (!subdev->func) { ret = subdev->object.oclass->ofuncs->fini(&subdev->object, suspend); if (ret) return ret; goto done; } if (subdev->func->fini) { int ret = subdev->func->fini(subdev, suspend); if (ret) { Loading @@ -104,6 +118,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) nvkm_rd32(device, 0x000200); } done: time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "%s completed in %lldus\n", action, time); return 0; Loading @@ -117,7 +132,7 @@ nvkm_subdev_preinit(struct nvkm_subdev *subdev) nvkm_trace(subdev, "preinit running...\n"); time = ktime_to_us(ktime_get()); if (subdev->func->preinit) { if (!subdev->object.oclass && subdev->func->preinit) { int ret = subdev->func->preinit(subdev); if (ret) { nvkm_error(subdev, "preinit failed, %d\n", ret); Loading @@ -139,6 +154,13 @@ nvkm_subdev_init(struct nvkm_subdev *subdev) nvkm_trace(subdev, "init running...\n"); time = ktime_to_us(ktime_get()); if (!subdev->func) { ret = subdev->object.oclass->ofuncs->init(&subdev->object); if (ret) return ret; goto done; } if (subdev->func->oneinit && !subdev->oneinit) { s64 time; nvkm_trace(subdev, "one-time init running...\n"); Loading @@ -162,6 +184,7 @@ nvkm_subdev_init(struct nvkm_subdev *subdev) } } done: time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "init completed in %lldus\n", time); return 0; Loading @@ -172,6 +195,12 @@ nvkm_subdev_del(struct nvkm_subdev **psubdev) { struct nvkm_subdev *subdev = *psubdev; s64 time; if (subdev && subdev->object.oclass) { subdev->object.oclass->ofuncs->dtor(&subdev->object); return; } if (subdev && !WARN_ON(!subdev->func)) { nvkm_trace(subdev, "destroy running...\n"); time = ktime_to_us(ktime_get()); Loading Loading @@ -211,8 +240,10 @@ nvkm_subdev(void *obj, int idx) struct nvkm_object *object = nv_object(obj); while (object && !nv_iclass(object, NV_SUBDEV_CLASS)) object = object->parent; if (object == NULL || !object->parent || nv_subidx(nv_subdev(object)) != idx) object = nv_device(obj)->subdev[idx]; if (object == NULL || !object->parent || nv_subidx(nv_subdev(object)) != idx) { struct nvkm_device *device = nv_device(obj); return nvkm_device_subdev(device, idx); } return object ? nv_subdev(object) : NULL; } Loading Loading @@ -266,8 +297,6 @@ _nvkm_subdev_fini(struct nvkm_object *object, bool suspend) void nvkm_subdev_destroy(struct nvkm_subdev *subdev) { int subidx = nv_hclass(subdev) & 0xff; nv_device(subdev)->subdev[subidx] = NULL; nvkm_object_destroy(&subdev->object); } Loading Loading
drivers/gpu/drm/nouveau/include/nvkm/core/device.h +48 −2 Original line number Diff line number Diff line Loading @@ -84,9 +84,9 @@ struct nvkm_device { struct nvkm_event event; const char *cname; u64 disable_mask; const struct nvkm_device_chip *chip; enum { NV_04 = 0x04, NV_10 = 0x10, Loading @@ -104,7 +104,6 @@ struct nvkm_device { u32 crystal; struct nvkm_oclass *oclass[NVDEV_SUBDEV_NR]; struct nvkm_object *subdev[NVDEV_SUBDEV_NR]; struct { struct notifier_block nb; Loading Loading @@ -153,6 +152,9 @@ struct nvkm_device { struct nouveau_platform_gpu *gpu; }; struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int index); struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int index); struct nvkm_device_func { struct nvkm_device_pci *(*pci)(struct nvkm_device *); struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); Loading @@ -164,6 +166,50 @@ struct nvkm_device_func { struct nvkm_device_quirk { }; struct nvkm_device_chip { const char *name; int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **); int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **); int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **); int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **); int (*devinit)(struct nvkm_device *, int idx, struct nvkm_devinit **); int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **); int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **); int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **); int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **); int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **); int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **); int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **); int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **); int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **); int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **); int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **); int (*dma )(struct nvkm_device *, int idx, struct nvkm_dmaeng **); int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **); int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **); int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **); int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **); int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **); }; struct nvkm_device *nvkm_device_find(u64 name); int nvkm_device_list(u64 *name, int size); Loading
drivers/gpu/drm/nouveau/nvkm/core/engine.c +10 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ static int nvkm_engine_fini(struct nvkm_subdev *obj, bool suspend) { struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev); if (engine->subdev.object.oclass) return engine->subdev.object.oclass->ofuncs->fini(&engine->subdev.object, suspend); if (engine->func->fini) return engine->func->fini(engine, suspend); return 0; Loading @@ -86,6 +88,9 @@ nvkm_engine_init(struct nvkm_subdev *obj) return ret; } if (engine->subdev.object.oclass) return engine->subdev.object.oclass->ofuncs->init(&engine->subdev.object); if (engine->func->oneinit && !engine->subdev.oneinit) { nvkm_trace(subdev, "one-time init running...\n"); time = ktime_to_us(ktime_get()); Loading @@ -110,6 +115,10 @@ static void * nvkm_engine_dtor(struct nvkm_subdev *obj) { struct nvkm_engine *engine = container_of(obj, typeof(*engine), subdev); if (engine->subdev.object.oclass) { engine->subdev.object.oclass->ofuncs->dtor(&engine->subdev.object); return NULL; } if (engine->func->dtor) return engine->func->dtor(engine); return engine; Loading Loading @@ -201,5 +210,6 @@ nvkm_engine_create_(struct nvkm_object *parent, struct nvkm_object *engobj, INIT_LIST_HEAD(&engine->contexts); spin_lock_init(&engine->lock); engine->subdev.func = &nvkm_engine_func; return 0; }
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +14 −11 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) struct nvkm_object *engctx = NULL; struct nvkm_object *object = NULL; struct nvkm_parent *parent; struct nvkm_object *engine; struct nvkm_engine *engine; struct nvkm_oclass *oclass; u32 _handle, _oclass; int ret; Loading @@ -117,7 +117,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) parent = nv_parent(handle->object); /* check that parent supports the requested subclass */ ret = nvkm_parent_sclass(&parent->object, _oclass, &engine, &oclass); ret = nvkm_parent_sclass(&parent->object, _oclass, (struct nvkm_object **)&engine, &oclass); if (ret) { nvif_debug(&parent->object, "illegal class 0x%04x\n", _oclass); goto fail_class; Loading @@ -128,18 +129,20 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) * state calculated at init (ie. default context construction) */ if (engine) { ret = nvkm_object_inc(engine); if (ret) engine = nvkm_engine_ref(engine); if (IS_ERR(engine)) { ret = PTR_ERR(engine); engine = NULL; goto fail_class; } } /* if engine requires it, create a context object to insert * between the parent and its children (eg. PGRAPH context) */ if (engine && nv_engine(engine)->cclass) { ret = nvkm_object_old(&parent->object, engine, nv_engine(engine)->cclass, data, size, &engctx); if (engine && engine->cclass) { ret = nvkm_object_old(&parent->object, &engine->subdev.object, engine->cclass, data, size, &engctx); if (ret) goto fail_engctx; } else { Loading @@ -147,7 +150,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) } /* finally, create new object and bind it to its handle */ ret = nvkm_object_old(engctx, engine, oclass, data, size, &object); ret = nvkm_object_old(engctx, &engine->subdev.object, oclass, data, size, &object); client->data = object; if (ret) goto fail_ctor; Loading Loading @@ -178,8 +182,7 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) fail_ctor: nvkm_object_ref(NULL, &engctx); fail_engctx: if (engine) nvkm_object_dec(engine, false); nvkm_engine_unref(&engine); fail_class: return ret; } Loading
drivers/gpu/drm/nouveau/nvkm/core/object.c +8 −40 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ nvkm_object_del(struct nvkm_object **pobject) if (object && !WARN_ON(!object->func)) { if (object->func->dtor) *pobject = object->func->dtor(object); nvkm_engine_unref(&object->engine); kfree(*pobject); *pobject = NULL; } Loading @@ -212,7 +213,7 @@ nvkm_object_ctor(const struct nvkm_object_func *func, { object->func = func; object->client = oclass->client; object->engine = oclass->engine; object->engine = nvkm_engine_ref(oclass->engine); object->oclass_name = oclass->base.oclass; object->handle = oclass->handle; object->parent = oclass->parent; Loading Loading @@ -251,10 +252,11 @@ nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size, } int nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engobj, struct nvkm_oclass *oclass, u32 pclass, int size, void **pobject) { struct nvkm_engine *engine = engobj ? nv_engine(engobj) : NULL; struct nvkm_object *object; object = *pobject = kzalloc(size, GFP_KERNEL); Loading @@ -262,7 +264,7 @@ nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine, return -ENOMEM; nvkm_object_ref(parent, &object->parent); nvkm_object_ref(engine, (struct nvkm_object **)&object->engine); object->engine = nvkm_engine_ref(engine); object->oclass = oclass; object->pclass = pclass; atomic_set(&object->refcount, 1); Loading @@ -287,7 +289,7 @@ _nvkm_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine, void nvkm_object_destroy(struct nvkm_object *object) { nvkm_object_ref(NULL, (struct nvkm_object **)&object->engine); nvkm_engine_unref(&object->engine); nvkm_object_ref(NULL, &object->parent); kfree(object); } Loading Loading @@ -333,6 +335,7 @@ nvkm_object_old(struct nvkm_object *parent, struct nvkm_object *engine, } if (ret == 0) { if (!nv_iclass(object, NV_SUBDEV_CLASS)) atomic_set(&object->refcount, 1); } Loading Loading @@ -370,14 +373,6 @@ nvkm_object_inc(struct nvkm_object *object) goto fail_parent; } if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); ret = nvkm_object_inc(&object->engine->subdev.object); mutex_unlock(&nv_subdev(object->engine)->mutex); if (ret) goto fail_engine; } ret = nvkm_object_init(object); atomic_set(&object->usecount, 1); if (ret) Loading @@ -386,12 +381,6 @@ nvkm_object_inc(struct nvkm_object *object) return 0; fail_self: if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_dec(&object->engine->subdev.object, false); mutex_unlock(&nv_subdev(object->engine)->mutex); } fail_engine: if (object->parent) nvkm_object_dec(object->parent, false); fail_parent: Loading @@ -405,12 +394,6 @@ nvkm_object_decf(struct nvkm_object *object) nvkm_object_fini(object, false); atomic_set(&object->usecount, 0); if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_dec(&object->engine->subdev.object, false); mutex_unlock(&nv_subdev(object->engine)->mutex); } if (object->parent) nvkm_object_dec(object->parent, false); Loading @@ -427,14 +410,6 @@ nvkm_object_decs(struct nvkm_object *object) if (ret) return ret; if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); ret = nvkm_object_dec(&object->engine->subdev.object, true); mutex_unlock(&nv_subdev(object->engine)->mutex); if (ret) goto fail_engine; } if (object->parent) { ret = nvkm_object_dec(object->parent, true); if (ret) Loading @@ -444,13 +419,6 @@ nvkm_object_decs(struct nvkm_object *object) return 0; fail_parent: if (object->engine) { mutex_lock(&nv_subdev(object->engine)->mutex); nvkm_object_inc(&object->engine->subdev.object); mutex_unlock(&nv_subdev(object->engine)->mutex); } fail_engine: nvkm_object_init(object); return ret; Loading
drivers/gpu/drm/nouveau/nvkm/core/subdev.c +34 −5 Original line number Diff line number Diff line Loading @@ -74,6 +74,12 @@ nvkm_subdev_name[64] = { void nvkm_subdev_intr(struct nvkm_subdev *subdev) { if (subdev->object.oclass) { if (subdev->intr) subdev->intr(subdev); return; } if (subdev->func->intr) subdev->func->intr(subdev); } Loading @@ -85,10 +91,18 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) const char *action = suspend ? "suspend" : "fini"; u32 pmc_enable = subdev->pmc_enable; s64 time; int ret; nvkm_trace(subdev, "%s running...\n", action); time = ktime_to_us(ktime_get()); if (!subdev->func) { ret = subdev->object.oclass->ofuncs->fini(&subdev->object, suspend); if (ret) return ret; goto done; } if (subdev->func->fini) { int ret = subdev->func->fini(subdev, suspend); if (ret) { Loading @@ -104,6 +118,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) nvkm_rd32(device, 0x000200); } done: time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "%s completed in %lldus\n", action, time); return 0; Loading @@ -117,7 +132,7 @@ nvkm_subdev_preinit(struct nvkm_subdev *subdev) nvkm_trace(subdev, "preinit running...\n"); time = ktime_to_us(ktime_get()); if (subdev->func->preinit) { if (!subdev->object.oclass && subdev->func->preinit) { int ret = subdev->func->preinit(subdev); if (ret) { nvkm_error(subdev, "preinit failed, %d\n", ret); Loading @@ -139,6 +154,13 @@ nvkm_subdev_init(struct nvkm_subdev *subdev) nvkm_trace(subdev, "init running...\n"); time = ktime_to_us(ktime_get()); if (!subdev->func) { ret = subdev->object.oclass->ofuncs->init(&subdev->object); if (ret) return ret; goto done; } if (subdev->func->oneinit && !subdev->oneinit) { s64 time; nvkm_trace(subdev, "one-time init running...\n"); Loading @@ -162,6 +184,7 @@ nvkm_subdev_init(struct nvkm_subdev *subdev) } } done: time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "init completed in %lldus\n", time); return 0; Loading @@ -172,6 +195,12 @@ nvkm_subdev_del(struct nvkm_subdev **psubdev) { struct nvkm_subdev *subdev = *psubdev; s64 time; if (subdev && subdev->object.oclass) { subdev->object.oclass->ofuncs->dtor(&subdev->object); return; } if (subdev && !WARN_ON(!subdev->func)) { nvkm_trace(subdev, "destroy running...\n"); time = ktime_to_us(ktime_get()); Loading Loading @@ -211,8 +240,10 @@ nvkm_subdev(void *obj, int idx) struct nvkm_object *object = nv_object(obj); while (object && !nv_iclass(object, NV_SUBDEV_CLASS)) object = object->parent; if (object == NULL || !object->parent || nv_subidx(nv_subdev(object)) != idx) object = nv_device(obj)->subdev[idx]; if (object == NULL || !object->parent || nv_subidx(nv_subdev(object)) != idx) { struct nvkm_device *device = nv_device(obj); return nvkm_device_subdev(device, idx); } return object ? nv_subdev(object) : NULL; } Loading Loading @@ -266,8 +297,6 @@ _nvkm_subdev_fini(struct nvkm_object *object, bool suspend) void nvkm_subdev_destroy(struct nvkm_subdev *subdev) { int subidx = nv_hclass(subdev) & 0xff; nv_device(subdev)->subdev[subidx] = NULL; nvkm_object_destroy(&subdev->object); } Loading