]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/nouveau/nouveau_mm.c
Merge branch 'staging-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[~andy/linux] / drivers / gpu / drm / nouveau / nouveau_mm.c
index 1640dec3b82322370abca80eca493e927c8b942e..b29ffb3d1408c6686f09c499c13e0d1a8f7fe05a 100644 (file)
@@ -27,7 +27,7 @@
 #include "nouveau_mm.h"
 
 static inline void
-region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a)
+region_put(struct nouveau_mm *mm, struct nouveau_mm_node *a)
 {
        list_del(&a->nl_entry);
        list_del(&a->fl_entry);
@@ -35,7 +35,7 @@ region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a)
 }
 
 static struct nouveau_mm_node *
-region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size)
+region_split(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
 {
        struct nouveau_mm_node *b;
 
@@ -57,33 +57,33 @@ region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size)
        return b;
 }
 
-#define node(root, dir) ((root)->nl_entry.dir == &rmm->nodes) ? NULL : \
+#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
        list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
 
 void
-nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this)
+nouveau_mm_put(struct nouveau_mm *mm, struct nouveau_mm_node *this)
 {
        struct nouveau_mm_node *prev = node(this, prev);
        struct nouveau_mm_node *next = node(this, next);
 
-       list_add(&this->fl_entry, &rmm->free);
+       list_add(&this->fl_entry, &mm->free);
        this->type = 0;
 
        if (prev && prev->type == 0) {
                prev->length += this->length;
-               region_put(rmm, this);
+               region_put(mm, this);
                this = prev;
        }
 
        if (next && next->type == 0) {
                next->offset  = this->offset;
                next->length += this->length;
-               region_put(rmm, this);
+               region_put(mm, this);
        }
 }
 
 int
-nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
+nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
               u32 align, struct nouveau_mm_node **pnode)
 {
        struct nouveau_mm_node *prev, *this, *next;
@@ -92,17 +92,17 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
        u32 splitoff;
        u32 s, e;
 
-       list_for_each_entry(this, &rmm->free, fl_entry) {
+       list_for_each_entry(this, &mm->free, fl_entry) {
                e = this->offset + this->length;
                s = this->offset;
 
                prev = node(this, prev);
                if (prev && prev->type != type)
-                       s = roundup(s, rmm->block_size);
+                       s = roundup(s, mm->block_size);
 
                next = node(this, next);
                if (next && next->type != type)
-                       e = rounddown(e, rmm->block_size);
+                       e = rounddown(e, mm->block_size);
 
                s  = (s + align_mask) & ~align_mask;
                e &= ~align_mask;
@@ -110,10 +110,10 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
                        continue;
 
                splitoff = s - this->offset;
-               if (splitoff && !region_split(rmm, this, splitoff))
+               if (splitoff && !region_split(mm, this, splitoff))
                        return -ENOMEM;
 
-               this = region_split(rmm, this, min(size, e - s));
+               this = region_split(mm, this, min(size, e - s));
                if (!this)
                        return -ENOMEM;
 
@@ -127,52 +127,49 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
 }
 
 int
-nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block)
+nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
 {
-       struct nouveau_mm *rmm;
-       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;
+       node->offset = roundup(offset, mm->block_size);
+       node->length = rounddown(offset + length, mm->block_size) - node->offset;
 
-       rmm = kzalloc(sizeof(*rmm), GFP_KERNEL);
-       if (!rmm) {
-               kfree(heap);
-               return -ENOMEM;
-       }
-       rmm->block_size = block;
-       mutex_init(&rmm->mutex);
-       INIT_LIST_HEAD(&rmm->nodes);
-       INIT_LIST_HEAD(&rmm->free);
-       list_add(&heap->nl_entry, &rmm->nodes);
-       list_add(&heap->fl_entry, &rmm->free);
-
-       *prmm = rmm;
+       list_add_tail(&node->nl_entry, &mm->nodes);
+       list_add_tail(&node->fl_entry, &mm->free);
+       mm->heap_nodes++;
        return 0;
 }
 
 int
-nouveau_mm_fini(struct nouveau_mm **prmm)
+nouveau_mm_fini(struct nouveau_mm *mm)
 {
-       struct nouveau_mm *rmm = *prmm;
        struct nouveau_mm_node *node, *heap =
-               list_first_entry(&rmm->nodes, struct nouveau_mm_node, nl_entry);
-
-       if (!list_is_singular(&rmm->nodes)) {
-               printk(KERN_ERR "nouveau_mm not empty at destroy time!\n");
-               list_for_each_entry(node, &rmm->nodes, nl_entry) {
-                       printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
-                              node->type, node->offset, node->length);
+               list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry);
+       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);
-       kfree(rmm);
-       *prmm = NULL;
        return 0;
 }