diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-23 20:14:07 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:03:56 -0400 |
commit | 987eec10dd76624d0edacdc7ecc7e1a6fc877373 (patch) | |
tree | b53b136797aa4aa55e4e78ba2c3f1d074b47beb4 /drivers/gpu/drm/nouveau/nouveau_mm.c | |
parent | 52d073318a4c32865e6439f7f6c247092a6f6af3 (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.c | 60 |
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 | ||
29 | static inline void | 29 | static inline void |
30 | region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a) | 30 | region_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 | ||
37 | static struct nouveau_mm_node * | 37 | static struct nouveau_mm_node * |
38 | region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size) | 38 | region_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 | ||
63 | void | 63 | void |
64 | nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this) | 64 | nouveau_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 | ||
85 | int | 85 | int |
86 | nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, | 86 | nouveau_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 | ||
129 | int | 129 | int |
130 | nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block) | 130 | nouveau_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 | ||
157 | int | 150 | int |
158 | nouveau_mm_fini(struct nouveau_mm **prmm) | 151 | nouveau_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 | } |