diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_sa.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_sa.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index 3bea7ba1e48..625f2d4f638 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -131,7 +131,7 @@ int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, | |||
131 | */ | 131 | */ |
132 | int radeon_sa_bo_new(struct radeon_device *rdev, | 132 | int radeon_sa_bo_new(struct radeon_device *rdev, |
133 | struct radeon_sa_manager *sa_manager, | 133 | struct radeon_sa_manager *sa_manager, |
134 | struct radeon_sa_bo *sa_bo, | 134 | struct radeon_sa_bo **sa_bo, |
135 | unsigned size, unsigned align) | 135 | unsigned size, unsigned align) |
136 | { | 136 | { |
137 | struct radeon_sa_bo *tmp; | 137 | struct radeon_sa_bo *tmp; |
@@ -140,6 +140,9 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
140 | 140 | ||
141 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); | 141 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); |
142 | BUG_ON(size > sa_manager->size); | 142 | BUG_ON(size > sa_manager->size); |
143 | |||
144 | *sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL); | ||
145 | |||
143 | spin_lock(&sa_manager->lock); | 146 | spin_lock(&sa_manager->lock); |
144 | 147 | ||
145 | /* no one ? */ | 148 | /* no one ? */ |
@@ -175,23 +178,30 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
175 | if ((sa_manager->size - offset) < size) { | 178 | if ((sa_manager->size - offset) < size) { |
176 | /* failed to find somethings big enough */ | 179 | /* failed to find somethings big enough */ |
177 | spin_unlock(&sa_manager->lock); | 180 | spin_unlock(&sa_manager->lock); |
181 | kfree(*sa_bo); | ||
182 | *sa_bo = NULL; | ||
178 | return -ENOMEM; | 183 | return -ENOMEM; |
179 | } | 184 | } |
180 | 185 | ||
181 | out: | 186 | out: |
182 | sa_bo->manager = sa_manager; | 187 | (*sa_bo)->manager = sa_manager; |
183 | sa_bo->soffset = offset; | 188 | (*sa_bo)->soffset = offset; |
184 | sa_bo->eoffset = offset + size; | 189 | (*sa_bo)->eoffset = offset + size; |
185 | list_add(&sa_bo->list, head); | 190 | list_add(&(*sa_bo)->list, head); |
186 | spin_unlock(&sa_manager->lock); | 191 | spin_unlock(&sa_manager->lock); |
187 | return 0; | 192 | return 0; |
188 | } | 193 | } |
189 | 194 | ||
190 | void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo) | 195 | void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo) |
191 | { | 196 | { |
192 | spin_lock(&sa_bo->manager->lock); | 197 | if (!sa_bo || !*sa_bo) |
193 | list_del_init(&sa_bo->list); | 198 | return; |
194 | spin_unlock(&sa_bo->manager->lock); | 199 | |
200 | spin_lock(&(*sa_bo)->manager->lock); | ||
201 | list_del_init(&(*sa_bo)->list); | ||
202 | spin_unlock(&(*sa_bo)->manager->lock); | ||
203 | kfree(*sa_bo); | ||
204 | *sa_bo = NULL; | ||
195 | } | 205 | } |
196 | 206 | ||
197 | #if defined(CONFIG_DEBUG_FS) | 207 | #if defined(CONFIG_DEBUG_FS) |