diff options
-rw-r--r-- | drivers/gpu/drm/drm_mm.c | 40 | ||||
-rw-r--r-- | include/drm/drm_mm.h | 7 |
2 files changed, 46 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a6bfc302ed90..c59515ba7e69 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -392,10 +392,36 @@ void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, | |||
392 | mm->scanned_blocks = 0; | 392 | mm->scanned_blocks = 0; |
393 | mm->scan_hit_start = 0; | 393 | mm->scan_hit_start = 0; |
394 | mm->scan_hit_size = 0; | 394 | mm->scan_hit_size = 0; |
395 | mm->scan_check_range = 0; | ||
395 | } | 396 | } |
396 | EXPORT_SYMBOL(drm_mm_init_scan); | 397 | EXPORT_SYMBOL(drm_mm_init_scan); |
397 | 398 | ||
398 | /** | 399 | /** |
400 | * Initializa lru scanning. | ||
401 | * | ||
402 | * This simply sets up the scanning routines with the parameters for the desired | ||
403 | * hole. This version is for range-restricted scans. | ||
404 | * | ||
405 | * Warning: As long as the scan list is non-empty, no other operations than | ||
406 | * adding/removing nodes to/from the scan list are allowed. | ||
407 | */ | ||
408 | void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, | ||
409 | unsigned alignment, | ||
410 | unsigned long start, | ||
411 | unsigned long end) | ||
412 | { | ||
413 | mm->scan_alignment = alignment; | ||
414 | mm->scan_size = size; | ||
415 | mm->scanned_blocks = 0; | ||
416 | mm->scan_hit_start = 0; | ||
417 | mm->scan_hit_size = 0; | ||
418 | mm->scan_start = start; | ||
419 | mm->scan_end = end; | ||
420 | mm->scan_check_range = 1; | ||
421 | } | ||
422 | EXPORT_SYMBOL(drm_mm_init_scan_with_range); | ||
423 | |||
424 | /** | ||
399 | * Add a node to the scan list that might be freed to make space for the desired | 425 | * Add a node to the scan list that might be freed to make space for the desired |
400 | * hole. | 426 | * hole. |
401 | * | 427 | * |
@@ -406,6 +432,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
406 | struct drm_mm *mm = node->mm; | 432 | struct drm_mm *mm = node->mm; |
407 | struct list_head *prev_free, *next_free; | 433 | struct list_head *prev_free, *next_free; |
408 | struct drm_mm_node *prev_node, *next_node; | 434 | struct drm_mm_node *prev_node, *next_node; |
435 | unsigned long adj_start; | ||
436 | unsigned long adj_end; | ||
409 | 437 | ||
410 | mm->scanned_blocks++; | 438 | mm->scanned_blocks++; |
411 | 439 | ||
@@ -452,7 +480,17 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
452 | node->free_stack.prev = prev_free; | 480 | node->free_stack.prev = prev_free; |
453 | node->free_stack.next = next_free; | 481 | node->free_stack.next = next_free; |
454 | 482 | ||
455 | if (check_free_hole(node->start, node->start + node->size, | 483 | if (mm->scan_check_range) { |
484 | adj_start = node->start < mm->scan_start ? | ||
485 | mm->scan_start : node->start; | ||
486 | adj_end = node->start + node->size > mm->scan_end ? | ||
487 | mm->scan_end : node->start + node->size; | ||
488 | } else { | ||
489 | adj_start = node->start; | ||
490 | adj_end = node->start + node->size; | ||
491 | } | ||
492 | |||
493 | if (check_free_hole(adj_start , adj_end, | ||
456 | mm->scan_size, mm->scan_alignment)) { | 494 | mm->scan_size, mm->scan_alignment)) { |
457 | mm->scan_hit_start = node->start; | 495 | mm->scan_hit_start = node->start; |
458 | mm->scan_hit_size = node->size; | 496 | mm->scan_hit_size = node->size; |
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index bf01531193d5..e39177778601 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h | |||
@@ -62,11 +62,14 @@ struct drm_mm { | |||
62 | struct list_head unused_nodes; | 62 | struct list_head unused_nodes; |
63 | int num_unused; | 63 | int num_unused; |
64 | spinlock_t unused_lock; | 64 | spinlock_t unused_lock; |
65 | unsigned int scan_check_range : 1; | ||
65 | unsigned scan_alignment; | 66 | unsigned scan_alignment; |
66 | unsigned long scan_size; | 67 | unsigned long scan_size; |
67 | unsigned long scan_hit_start; | 68 | unsigned long scan_hit_start; |
68 | unsigned scan_hit_size; | 69 | unsigned scan_hit_size; |
69 | unsigned scanned_blocks; | 70 | unsigned scanned_blocks; |
71 | unsigned long scan_start; | ||
72 | unsigned long scan_end; | ||
70 | }; | 73 | }; |
71 | 74 | ||
72 | /* | 75 | /* |
@@ -145,6 +148,10 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) | |||
145 | 148 | ||
146 | void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, | 149 | void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, |
147 | unsigned alignment); | 150 | unsigned alignment); |
151 | void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, | ||
152 | unsigned alignment, | ||
153 | unsigned long start, | ||
154 | unsigned long end); | ||
148 | int drm_mm_scan_add_block(struct drm_mm_node *node); | 155 | int drm_mm_scan_add_block(struct drm_mm_node *node); |
149 | int drm_mm_scan_remove_block(struct drm_mm_node *node); | 156 | int drm_mm_scan_remove_block(struct drm_mm_node *node); |
150 | 157 | ||