diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-24 10:23:20 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 16:04:00 +1000 |
commit | a12036ba2c0a190c93e5238c5f32fdb8c023c068 (patch) | |
tree | 604f365447a806e07f31589a655b1c0a8494f669 /drivers/gpu/drm/nouveau/nouveau_mm.c | |
parent | 987eec10dd76624d0edacdc7ecc7e1a6fc877373 (diff) | |
download | talos-obmc-linux-a12036ba2c0a190c93e5238c5f32fdb8c023c068.tar.gz talos-obmc-linux-a12036ba2c0a190c93e5238c5f32fdb8c023c068.zip |
drm/nouveau: allow a nouveau_mm to be created with holes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mm.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mm.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c index 75b5dd93a32f..b29ffb3d1408 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -129,21 +129,25 @@ nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc, int nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) { - struct nouveau_mm_node *heap; + struct nouveau_mm_node *node; + + if (block) { + mutex_init(&mm->mutex); + INIT_LIST_HEAD(&mm->nodes); + INIT_LIST_HEAD(&mm->free); + mm->block_size = block; + mm->heap_nodes = 0; + } - heap = kzalloc(sizeof(*heap), GFP_KERNEL); - if (!heap) + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) return -ENOMEM; - heap->offset = roundup(offset, block); - heap->length = rounddown(offset + length, block) - heap->offset; - - mutex_init(&mm->mutex); - mm->block_size = block; - INIT_LIST_HEAD(&mm->nodes); - INIT_LIST_HEAD(&mm->free); + node->offset = roundup(offset, mm->block_size); + node->length = rounddown(offset + length, mm->block_size) - node->offset; - list_add(&heap->nl_entry, &mm->nodes); - list_add(&heap->fl_entry, &mm->free); + list_add_tail(&node->nl_entry, &mm->nodes); + list_add_tail(&node->fl_entry, &mm->free); + mm->heap_nodes++; return 0; } @@ -152,15 +156,18 @@ nouveau_mm_fini(struct nouveau_mm *mm) { struct nouveau_mm_node *node, *heap = list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry); - - if (!list_is_singular(&mm->nodes)) { - printk(KERN_ERR "nouveau_mm not empty at destroy time!\n"); - list_for_each_entry(node, &mm->nodes, nl_entry) { - printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", - node->type, node->offset, node->length); + int nodes = 0; + + list_for_each_entry(node, &mm->nodes, nl_entry) { + if (nodes++ == mm->heap_nodes) { + printk(KERN_ERR "nouveau_mm in use at destroy time!\n"); + list_for_each_entry(node, &mm->nodes, nl_entry) { + printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", + node->type, node->offset, node->length); + } + WARN_ON(1); + return -EBUSY; } - WARN_ON(1); - return -EBUSY; } kfree(heap); |