aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_mm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-06-23 20:14:07 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:03:56 -0400
commit987eec10dd76624d0edacdc7ecc7e1a6fc877373 (patch)
treeb53b136797aa4aa55e4e78ba2c3f1d074b47beb4 /drivers/gpu/drm/nouveau/nouveau_mm.c
parent52d073318a4c32865e6439f7f6c247092a6f6af3 (diff)
drm/nouveau: embed nouveau_mm
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.c60
1 files changed, 25 insertions, 35 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c
index 1640dec3b823..75b5dd93a32f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.c
@@ -27,7 +27,7 @@
27#include "nouveau_mm.h" 27#include "nouveau_mm.h"
28 28
29static inline void 29static inline void
30region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a) 30region_put(struct nouveau_mm *mm, struct nouveau_mm_node *a)
31{ 31{
32 list_del(&a->nl_entry); 32 list_del(&a->nl_entry);
33 list_del(&a->fl_entry); 33 list_del(&a->fl_entry);
@@ -35,7 +35,7 @@ region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a)
35} 35}
36 36
37static struct nouveau_mm_node * 37static struct nouveau_mm_node *
38region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size) 38region_split(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
39{ 39{
40 struct nouveau_mm_node *b; 40 struct nouveau_mm_node *b;
41 41
@@ -57,33 +57,33 @@ region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size)
57 return b; 57 return b;
58} 58}
59 59
60#define node(root, dir) ((root)->nl_entry.dir == &rmm->nodes) ? NULL : \ 60#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
61 list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry) 61 list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
62 62
63void 63void
64nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this) 64nouveau_mm_put(struct nouveau_mm *mm, struct nouveau_mm_node *this)
65{ 65{
66 struct nouveau_mm_node *prev = node(this, prev); 66 struct nouveau_mm_node *prev = node(this, prev);
67 struct nouveau_mm_node *next = node(this, next); 67 struct nouveau_mm_node *next = node(this, next);
68 68
69 list_add(&this->fl_entry, &rmm->free); 69 list_add(&this->fl_entry, &mm->free);
70 this->type = 0; 70 this->type = 0;
71 71
72 if (prev && prev->type == 0) { 72 if (prev && prev->type == 0) {
73 prev->length += this->length; 73 prev->length += this->length;
74 region_put(rmm, this); 74 region_put(mm, this);
75 this = prev; 75 this = prev;
76 } 76 }
77 77
78 if (next && next->type == 0) { 78 if (next && next->type == 0) {
79 next->offset = this->offset; 79 next->offset = this->offset;
80 next->length += this->length; 80 next->length += this->length;
81 region_put(rmm, this); 81 region_put(mm, this);
82 } 82 }
83} 83}
84 84
85int 85int
86nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, 86nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
87 u32 align, struct nouveau_mm_node **pnode) 87 u32 align, struct nouveau_mm_node **pnode)
88{ 88{
89 struct nouveau_mm_node *prev, *this, *next; 89 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,
92 u32 splitoff; 92 u32 splitoff;
93 u32 s, e; 93 u32 s, e;
94 94
95 list_for_each_entry(this, &rmm->free, fl_entry) { 95 list_for_each_entry(this, &mm->free, fl_entry) {
96 e = this->offset + this->length; 96 e = this->offset + this->length;
97 s = this->offset; 97 s = this->offset;
98 98
99 prev = node(this, prev); 99 prev = node(this, prev);
100 if (prev && prev->type != type) 100 if (prev && prev->type != type)
101 s = roundup(s, rmm->block_size); 101 s = roundup(s, mm->block_size);
102 102
103 next = node(this, next); 103 next = node(this, next);
104 if (next && next->type != type) 104 if (next && next->type != type)
105 e = rounddown(e, rmm->block_size); 105 e = rounddown(e, mm->block_size);
106 106
107 s = (s + align_mask) & ~align_mask; 107 s = (s + align_mask) & ~align_mask;
108 e &= ~align_mask; 108 e &= ~align_mask;
@@ -110,10 +110,10 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
110 continue; 110 continue;
111 111
112 splitoff = s - this->offset; 112 splitoff = s - this->offset;
113 if (splitoff && !region_split(rmm, this, splitoff)) 113 if (splitoff && !region_split(mm, this, splitoff))
114 return -ENOMEM; 114 return -ENOMEM;
115 115
116 this = region_split(rmm, this, min(size, e - s)); 116 this = region_split(mm, this, min(size, e - s));
117 if (!this) 117 if (!this)
118 return -ENOMEM; 118 return -ENOMEM;
119 119
@@ -127,9 +127,8 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
127} 127}
128 128
129int 129int
130nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block) 130nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
131{ 131{
132 struct nouveau_mm *rmm;
133 struct nouveau_mm_node *heap; 132 struct nouveau_mm_node *heap;
134 133
135 heap = kzalloc(sizeof(*heap), GFP_KERNEL); 134 heap = kzalloc(sizeof(*heap), GFP_KERNEL);
@@ -138,32 +137,25 @@ nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block)
138 heap->offset = roundup(offset, block); 137 heap->offset = roundup(offset, block);
139 heap->length = rounddown(offset + length, block) - heap->offset; 138 heap->length = rounddown(offset + length, block) - heap->offset;
140 139
141 rmm = kzalloc(sizeof(*rmm), GFP_KERNEL); 140 mutex_init(&mm->mutex);
142 if (!rmm) { 141 mm->block_size = block;
143 kfree(heap); 142 INIT_LIST_HEAD(&mm->nodes);
144 return -ENOMEM; 143 INIT_LIST_HEAD(&mm->free);
145 } 144
146 rmm->block_size = block; 145 list_add(&heap->nl_entry, &mm->nodes);
147 mutex_init(&rmm->mutex); 146 list_add(&heap->fl_entry, &mm->free);
148 INIT_LIST_HEAD(&rmm->nodes);
149 INIT_LIST_HEAD(&rmm->free);
150 list_add(&heap->nl_entry, &rmm->nodes);
151 list_add(&heap->fl_entry, &rmm->free);
152
153 *prmm = rmm;
154 return 0; 147 return 0;
155} 148}
156 149
157int 150int
158nouveau_mm_fini(struct nouveau_mm **prmm) 151nouveau_mm_fini(struct nouveau_mm *mm)
159{ 152{
160 struct nouveau_mm *rmm = *prmm;
161 struct nouveau_mm_node *node, *heap = 153 struct nouveau_mm_node *node, *heap =
162 list_first_entry(&rmm->nodes, struct nouveau_mm_node, nl_entry); 154 list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry);
163 155
164 if (!list_is_singular(&rmm->nodes)) { 156 if (!list_is_singular(&mm->nodes)) {
165 printk(KERN_ERR "nouveau_mm not empty at destroy time!\n"); 157 printk(KERN_ERR "nouveau_mm not empty at destroy time!\n");
166 list_for_each_entry(node, &rmm->nodes, nl_entry) { 158 list_for_each_entry(node, &mm->nodes, nl_entry) {
167 printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", 159 printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
168 node->type, node->offset, node->length); 160 node->type, node->offset, node->length);
169 } 161 }
@@ -172,7 +164,5 @@ nouveau_mm_fini(struct nouveau_mm **prmm)
172 } 164 }
173 165
174 kfree(heap); 166 kfree(heap);
175 kfree(rmm);
176 *prmm = NULL;
177 return 0; 167 return 0;
178} 168}