diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 5c34416cb6..c826980bf7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -88,12 +88,20 @@ nvkm_vram_dtor(struct nvkm_memory *memory) struct nvkm_vram *vram = nvkm_vram(memory); struct nvkm_mm_node *next = vram->mn; struct nvkm_mm_node *node; - mutex_lock(&vram->ram->mutex); - while ((node = next)) { - next = node->next; - nvkm_mm_free(&vram->ram->vram, &node); + + if (next) { + if (likely(next->nl_entry.next)){ + mutex_lock(&vram->ram->mutex); + while ((node = next)) { + next = node->next; + nvkm_mm_free(&vram->ram->vram, &node); + } + mutex_unlock(&vram->ram->mutex); + } else { + kfree(vram->mn); + } } - mutex_unlock(&vram->ram->mutex); + return vram; } @@ -109,6 +117,34 @@ nvkm_vram = { }; int +nvkm_ram_wrap(struct nvkm_device *device, u64 addr, u64 size, + struct nvkm_memory **pmemory) +{ + struct nvkm_ram *ram; + struct nvkm_vram *vram; + + if (!device->fb || !(ram = device->fb->ram)) + return -ENODEV; + ram = device->fb->ram; + + if (!(vram = kzalloc(sizeof(*vram), GFP_KERNEL))) + return -ENOMEM; + + nvkm_memory_ctor(&nvkm_vram, &vram->memory); + vram->ram = ram; + vram->page = NVKM_RAM_MM_SHIFT; + *pmemory = &vram->memory; + + vram->mn = kzalloc(sizeof(*vram->mn), GFP_KERNEL); + if (!vram->mn) + return -ENOMEM; + + vram->mn->offset = addr >> NVKM_RAM_MM_SHIFT; + vram->mn->length = size >> NVKM_RAM_MM_SHIFT; + return 0; +} + +int nvkm_ram_get(struct nvkm_device *device, u8 heap, u8 type, u8 rpage, u64 size, bool contig, bool back, struct nvkm_memory **pmemory) { |