From: Ben Skeggs <bskeggs@redhat.com>
Date: Fri, 24 Jun 2011 00:23:20 +0000 (+1000)
Subject: drm/nouveau: allow a nouveau_mm to be created with holes
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a12036ba2c0a190c93e5238c5f32fdb8c023c068;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git

drm/nouveau: allow a nouveau_mm to be created with holes

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---

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);
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h
index b8fe9088b9ed..57a600c35c95 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.h
@@ -42,6 +42,7 @@ struct nouveau_mm {
 	struct mutex mutex;
 
 	u32 block_size;
+	int heap_nodes;
 };
 
 int  nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);