Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3030 → Rev 3031

/drivers/video/drm/drm_mm.c
41,10 → 41,11
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
 
#include "drmP.h"
#include "drm_mm.h"
#include <drm/drmP.h>
#include <drm/drm_mm.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/export.h>
 
#define MM_UNUSED_TARGET 4
 
117,39 → 118,46
 
static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
struct drm_mm_node *node,
unsigned long size, unsigned alignment)
unsigned long size, unsigned alignment,
unsigned long color)
{
struct drm_mm *mm = hole_node->mm;
unsigned long tmp = 0, wasted = 0;
unsigned long hole_start = drm_mm_hole_node_start(hole_node);
unsigned long hole_end = drm_mm_hole_node_end(hole_node);
unsigned long adj_start = hole_start;
unsigned long adj_end = hole_end;
 
BUG_ON(!hole_node->hole_follows || node->allocated);
 
if (alignment)
tmp = hole_start % alignment;
if (mm->color_adjust)
mm->color_adjust(hole_node, color, &adj_start, &adj_end);
 
if (!tmp) {
if (alignment) {
unsigned tmp = adj_start % alignment;
if (tmp)
adj_start += alignment - tmp;
}
 
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
list_del_init(&hole_node->hole_stack);
} else
wasted = alignment - tmp;
list_del(&hole_node->hole_stack);
}
 
node->start = hole_start + wasted;
node->start = adj_start;
node->size = size;
node->mm = mm;
node->color = color;
node->allocated = 1;
 
INIT_LIST_HEAD(&node->hole_stack);
list_add(&node->node_list, &hole_node->node_list);
 
BUG_ON(node->start + node->size > hole_end);
BUG_ON(node->start + node->size > adj_end);
 
node->hole_follows = 0;
if (node->start + node->size < hole_end) {
list_add(&node->hole_stack, &mm->hole_stack);
node->hole_follows = 1;
} else {
node->hole_follows = 0;
}
}
 
156,6 → 164,7
struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
unsigned long size,
unsigned alignment,
unsigned long color,
int atomic)
{
struct drm_mm_node *node;
164,7 → 173,7
if (unlikely(node == NULL))
return NULL;
 
drm_mm_insert_helper(hole_node, node, size, alignment);
drm_mm_insert_helper(hole_node, node, size, alignment, color);
 
return node;
}
180,11 → 189,11
{
struct drm_mm_node *hole_node;
 
hole_node = drm_mm_search_free(mm, size, alignment, 0);
hole_node = drm_mm_search_free(mm, size, alignment, false);
if (!hole_node)
return -ENOSPC;
 
drm_mm_insert_helper(hole_node, node, size, alignment);
drm_mm_insert_helper(hole_node, node, size, alignment, 0);
 
return 0;
}
193,44 → 202,50
static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
struct drm_mm_node *node,
unsigned long size, unsigned alignment,
unsigned long color,
unsigned long start, unsigned long end)
{
struct drm_mm *mm = hole_node->mm;
unsigned long tmp = 0, wasted = 0;
unsigned long hole_start = drm_mm_hole_node_start(hole_node);
unsigned long hole_end = drm_mm_hole_node_end(hole_node);
unsigned long adj_start = hole_start;
unsigned long adj_end = hole_end;
 
BUG_ON(!hole_node->hole_follows || node->allocated);
 
if (hole_start < start)
wasted += start - hole_start;
if (alignment)
tmp = (hole_start + wasted) % alignment;
if (mm->color_adjust)
mm->color_adjust(hole_node, color, &adj_start, &adj_end);
 
if (adj_start < start)
adj_start = start;
 
if (alignment) {
unsigned tmp = adj_start % alignment;
if (tmp)
wasted += alignment - tmp;
adj_start += alignment - tmp;
}
 
if (!wasted) {
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
list_del_init(&hole_node->hole_stack);
list_del(&hole_node->hole_stack);
}
 
node->start = hole_start + wasted;
node->start = adj_start;
node->size = size;
node->mm = mm;
node->color = color;
node->allocated = 1;
 
INIT_LIST_HEAD(&node->hole_stack);
list_add(&node->node_list, &hole_node->node_list);
 
BUG_ON(node->start + node->size > hole_end);
BUG_ON(node->start + node->size > adj_end);
BUG_ON(node->start + node->size > end);
 
node->hole_follows = 0;
if (node->start + node->size < hole_end) {
list_add(&node->hole_stack, &mm->hole_stack);
node->hole_follows = 1;
} else {
node->hole_follows = 0;
}
}
 
237,6 → 252,7
struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node,
unsigned long size,
unsigned alignment,
unsigned long color,
unsigned long start,
unsigned long end,
int atomic)
247,7 → 263,7
if (unlikely(node == NULL))
return NULL;
 
drm_mm_insert_helper_range(hole_node, node, size, alignment,
drm_mm_insert_helper_range(hole_node, node, size, alignment, color,
start, end);
 
return node;
266,11 → 282,11
struct drm_mm_node *hole_node;
 
hole_node = drm_mm_search_free_in_range(mm, size, alignment,
start, end, 0);
start, end, false);
if (!hole_node)
return -ENOSPC;
 
drm_mm_insert_helper_range(hole_node, node, size, alignment,
drm_mm_insert_helper_range(hole_node, node, size, alignment, 0,
start, end);
 
return 0;
335,8 → 351,6
static int check_free_hole(unsigned long start, unsigned long end,
unsigned long size, unsigned alignment)
{
unsigned wasted = 0;
 
if (end - start < size)
return 0;
 
343,19 → 357,17
if (alignment) {
unsigned tmp = start % alignment;
if (tmp)
wasted = alignment - tmp;
start += alignment - tmp;
}
 
if (end >= start + size + wasted) {
return 1;
return end >= start + size;
}
 
return 0;
}
 
struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
unsigned long size,
unsigned alignment, int best_match)
unsigned alignment,
unsigned long color,
bool best_match)
{
struct drm_mm_node *entry;
struct drm_mm_node *best;
367,10 → 379,17
best_size = ~0UL;
 
list_for_each_entry(entry, &mm->hole_stack, hole_stack) {
unsigned long adj_start = drm_mm_hole_node_start(entry);
unsigned long adj_end = drm_mm_hole_node_end(entry);
 
if (mm->color_adjust) {
mm->color_adjust(entry, color, &adj_start, &adj_end);
if (adj_end <= adj_start)
continue;
}
 
BUG_ON(!entry->hole_follows);
if (!check_free_hole(drm_mm_hole_node_start(entry),
drm_mm_hole_node_end(entry),
size, alignment))
if (!check_free_hole(adj_start, adj_end, size, alignment))
continue;
 
if (!best_match)
384,14 → 403,15
 
return best;
}
EXPORT_SYMBOL(drm_mm_search_free);
EXPORT_SYMBOL(drm_mm_search_free_generic);
 
struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
unsigned long size,
unsigned alignment,
unsigned long color,
unsigned long start,
unsigned long end,
int best_match)
bool best_match)
{
struct drm_mm_node *entry;
struct drm_mm_node *best;
409,6 → 429,13
end : drm_mm_hole_node_end(entry);
 
BUG_ON(!entry->hole_follows);
 
if (mm->color_adjust) {
mm->color_adjust(entry, color, &adj_start, &adj_end);
if (adj_end <= adj_start)
continue;
}
 
if (!check_free_hole(adj_start, adj_end, size, alignment))
continue;
 
423,7 → 450,7
 
return best;
}
EXPORT_SYMBOL(drm_mm_search_free_in_range);
EXPORT_SYMBOL(drm_mm_search_free_in_range_generic);
 
/**
* Moves an allocation. To be used with embedded struct drm_mm_node.
436,6 → 463,7
new->mm = old->mm;
new->start = old->start;
new->size = old->size;
new->color = old->color;
 
old->allocated = 0;
new->allocated = 1;
451,9 → 479,12
* Warning: As long as the scan list is non-empty, no other operations than
* adding/removing nodes to/from the scan list are allowed.
*/
void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
unsigned alignment)
void drm_mm_init_scan(struct drm_mm *mm,
unsigned long size,
unsigned alignment,
unsigned long color)
{
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
mm->scanned_blocks = 0;
473,11 → 504,14
* Warning: As long as the scan list is non-empty, no other operations than
* adding/removing nodes to/from the scan list are allowed.
*/
void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
void drm_mm_init_scan_with_range(struct drm_mm *mm,
unsigned long size,
unsigned alignment,
unsigned long color,
unsigned long start,
unsigned long end)
{
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
mm->scanned_blocks = 0;
521,14 → 555,18
 
hole_start = drm_mm_hole_node_start(prev_node);
hole_end = drm_mm_hole_node_end(prev_node);
if (mm->scan_check_range) {
adj_start = hole_start < mm->scan_start ?
mm->scan_start : hole_start;
adj_end = hole_end > mm->scan_end ?
mm->scan_end : hole_end;
} else {
 
adj_start = hole_start;
adj_end = hole_end;
 
if (mm->color_adjust)
mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end);
 
if (mm->scan_check_range) {
if (adj_start < mm->scan_start)
adj_start = mm->scan_start;
if (adj_end > mm->scan_end)
adj_end = mm->scan_end;
}
 
if (check_free_hole(adj_start , adj_end,
615,6 → 653,8
mm->head_node.size = start - mm->head_node.start;
list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
 
mm->color_adjust = NULL;
 
return 0;
}
EXPORT_SYMBOL(drm_mm_init);