aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-07-30 16:49:57 +1000
committerDave Airlie <airlied@redhat.com>2013-07-30 16:49:57 +1000
commite9e3c8a20b2ac89a5770a6bb0a1d0dafc7f0edb0 (patch)
tree160b7db4ee3b4aaa232f6bd788eef82ce609fdc3 /drivers/gpu/drm/nouveau/core/subdev/vm/base.c
parentMerge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos (diff)
parentdrm/nouveau: fix semaphore dmabuf obj (diff)
downloadlinux-dev-e9e3c8a20b2ac89a5770a6bb0a1d0dafc7f0edb0.tar.xz
linux-dev-e9e3c8a20b2ac89a5770a6bb0a1d0dafc7f0edb0.zip
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6
nouveau fixes a number of regressions and a few user triggerable oops since -rc1. Along with a few mpeg engine fixes. * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: drm/nouveau: fix semaphore dmabuf obj drm/nouveau/vm: make vm refcount into a kref drm/nv31/mpeg: don't recognize nv3x cards as having nv44 graph class drm/nv40/mpeg: write magic value to channel object to make it work drm/nouveau: fix size check for cards without vm drm/nv50-/disp: remove dcb_outp_match call, and related variables drm/nva3-/disp: fix hda eld writing, needs to be padded drm/nv31/mpeg: fix mpeg engine initialization drm/nv50/mc: include vp in the fb error reporting mask drm/nouveau: fix null pointer dereference in poll_changed drm/nv50/gpio: post-nv92 cards have 32 interrupt lines drm/nvc0/fb: take lock in nvc0_ram_put() drm/nouveau/core: xtensa firmware size needs to be 0x40000 no matter what
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/vm/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
index 67fcb6c852ac..ef3133e7575c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
@@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
INIT_LIST_HEAD(&vm->pgd_list);
vm->vmm = vmm;
- vm->refcount = 1;
+ kref_init(&vm->refcount);
vm->fpde = offset >> (vmm->pgt_bits + 12);
vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12);
@@ -441,8 +441,9 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
}
static void
-nouveau_vm_del(struct nouveau_vm *vm)
+nouveau_vm_del(struct kref *kref)
{
+ struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount);
struct nouveau_vm_pgd *vpgd, *tmp;
list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
@@ -458,27 +459,19 @@ int
nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr,
struct nouveau_gpuobj *pgd)
{
- struct nouveau_vm *vm;
- int ret;
-
- vm = ref;
- if (vm) {
- ret = nouveau_vm_link(vm, pgd);
+ if (ref) {
+ int ret = nouveau_vm_link(ref, pgd);
if (ret)
return ret;
- vm->refcount++;
+ kref_get(&ref->refcount);
}
- vm = *ptr;
- *ptr = ref;
-
- if (vm) {
- nouveau_vm_unlink(vm, pgd);
-
- if (--vm->refcount == 0)
- nouveau_vm_del(vm);
+ if (*ptr) {
+ nouveau_vm_unlink(*ptr, pgd);
+ kref_put(&(*ptr)->refcount, nouveau_vm_del);
}
+ *ptr = ref;
return 0;
}