Commit 6b702462 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (50 commits)
  drm: include kernel list header file in hashtab header
  drm: Export hash table functionality.
  drm: Split out the mm declarations in a separate header. Add atomic operations.
  drm/radeon: add support for RV790.
  drm/radeon: add rv740 drm support.
  drm_calloc_large: check right size, check integer overflow, use GFP_ZERO
  drm: Eliminate magic I2C frobbing when reading EDID
  drm/i915: duplicate desired mode for use by fbcon.
  drm/via: vfree() no need checking before calling it
  drm: Replace DRM_DEBUG with DRM_DEBUG_DRIVER in i915 driver
  drm: Replace DRM_DEBUG with DRM_DEBUG_MODE in drm_mode
  drm/i915: Replace DRM_DEBUG with DRM_DEBUG_KMS in intel_sdvo
  drm/i915: replace DRM_DEBUG with DRM_DEBUG_KMS in intel_lvds
  drm: add separate drm debugging levels
  radeon: remove _DRM_DRIVER from the preadded sarea map
  drm: don't associate _DRM_DRIVER maps with a master
  drm: simplify kcalloc() call to kzalloc().
  intelfb: fix spelling of "CLOCK"
  drm: fix LOCK_TEST_WITH_RETURN macro
  drm/i915: Hook connector to encoder during load detection (fixes tv/vga detect)
  ...
parents 947ec0b0 3c24475c
...@@ -46,6 +46,10 @@ ...@@ -46,6 +46,10 @@
#define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 #define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22
#define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30
#define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32
#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
/* cover 915 and 945 variants */ /* cover 915 and 945 variants */
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
...@@ -75,7 +79,9 @@ ...@@ -75,7 +79,9 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB) agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB)
extern int agp_memory_reserved; extern int agp_memory_reserved;
...@@ -1211,6 +1217,8 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) ...@@ -1211,6 +1217,8 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
case PCI_DEVICE_ID_INTEL_Q45_HB: case PCI_DEVICE_ID_INTEL_Q45_HB:
case PCI_DEVICE_ID_INTEL_G45_HB: case PCI_DEVICE_ID_INTEL_G45_HB:
case PCI_DEVICE_ID_INTEL_G41_HB: case PCI_DEVICE_ID_INTEL_G41_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
*gtt_offset = *gtt_size = MB(2); *gtt_offset = *gtt_size = MB(2);
break; break;
default: default:
...@@ -2186,6 +2194,10 @@ static const struct intel_driver_description { ...@@ -2186,6 +2194,10 @@ static const struct intel_driver_description {
"G45/G43", NULL, &intel_i965_driver }, "G45/G43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
"G41", NULL, &intel_i965_driver }, "G41", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0,
"IGDNG/D", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
"IGDNG/M", NULL, &intel_i965_driver },
{ 0, 0, 0, NULL, NULL, NULL } { 0, 0, 0, NULL, NULL, NULL }
}; };
...@@ -2387,6 +2399,8 @@ static struct pci_device_id agp_intel_pci_table[] = { ...@@ -2387,6 +2399,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_Q45_HB), ID(PCI_DEVICE_ID_INTEL_Q45_HB),
ID(PCI_DEVICE_ID_INTEL_G45_HB), ID(PCI_DEVICE_ID_INTEL_G45_HB),
ID(PCI_DEVICE_ID_INTEL_G41_HB), ID(PCI_DEVICE_ID_INTEL_G41_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
{ } { }
}; };
......
...@@ -371,7 +371,8 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, ...@@ -371,7 +371,8 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
list->user_token = list->hash.key << PAGE_SHIFT; list->user_token = list->hash.key << PAGE_SHIFT;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
list->master = dev->primary->master; if (!(map->flags & _DRM_DRIVER))
list->master = dev->primary->master;
*maplist = list; *maplist = list;
return 0; return 0;
} }
......
...@@ -589,85 +589,13 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, ...@@ -589,85 +589,13 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
} }
EXPORT_SYMBOL(drm_do_probe_ddc_edid); EXPORT_SYMBOL(drm_do_probe_ddc_edid);
/**
* Get EDID information.
*
* \param adapter : i2c device adaptor.
* \param buf : EDID data buffer to be filled
* \param len : EDID data buffer length
* \return 0 on success or -1 on failure.
*
* Initialize DDC, then fetch EDID information
* by calling drm_do_probe_ddc_edid function.
*/
static int drm_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, int len)
{
struct i2c_algo_bit_data *algo_data = adapter->algo_data;
int i, j;
int ret = -1;
algo_data->setscl(algo_data->data, 1);
for (i = 0; i < 1; i++) {
/* For some old monitors we need the
* following process to initialize/stop DDC
*/
algo_data->setsda(algo_data->data, 1);
msleep(13);
algo_data->setscl(algo_data->data, 1);
for (j = 0; j < 5; j++) {
msleep(10);
if (algo_data->getscl(algo_data->data))
break;
}
if (j == 5)
continue;
algo_data->setsda(algo_data->data, 0);
msleep(15);
algo_data->setscl(algo_data->data, 0);
msleep(15);
algo_data->setsda(algo_data->data, 1);
msleep(15);
/* Do the real work */
ret = drm_do_probe_ddc_edid(adapter, buf, len);
algo_data->setsda(algo_data->data, 0);
algo_data->setscl(algo_data->data, 0);
msleep(15);
algo_data->setscl(algo_data->data, 1);
for (j = 0; j < 10; j++) {
msleep(10);
if (algo_data->getscl(algo_data->data))
break;
}
algo_data->setsda(algo_data->data, 1);
msleep(15);
algo_data->setscl(algo_data->data, 0);
algo_data->setsda(algo_data->data, 0);
if (ret == 0)
break;
}
/* Release the DDC lines when done or the Apple Cinema HD display
* will switch off
*/
algo_data->setsda(algo_data->data, 1);
algo_data->setscl(algo_data->data, 1);
return ret;
}
static int drm_ddc_read_edid(struct drm_connector *connector, static int drm_ddc_read_edid(struct drm_connector *connector,
struct i2c_adapter *adapter, struct i2c_adapter *adapter,
char *buf, int len) char *buf, int len)
{ {
int ret; int ret;
ret = drm_ddc_read(adapter, buf, len); ret = drm_do_probe_ddc_edid(adapter, buf, len);
if (ret != 0) { if (ret != 0) {
dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
......
...@@ -133,7 +133,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) ...@@ -133,7 +133,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
BUG_ON((size & (PAGE_SIZE - 1)) != 0); BUG_ON((size & (PAGE_SIZE - 1)) != 0);
obj = kcalloc(1, sizeof(*obj), GFP_KERNEL); obj = kzalloc(sizeof(*obj), GFP_KERNEL);
obj->dev = dev; obj->dev = dev;
obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
......
...@@ -62,6 +62,7 @@ int drm_ht_create(struct drm_open_hash *ht, unsigned int order) ...@@ -62,6 +62,7 @@ int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(drm_ht_create);
void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key) void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key)
{ {
...@@ -156,6 +157,7 @@ int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *it ...@@ -156,6 +157,7 @@ int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *it
} }
return 0; return 0;
} }
EXPORT_SYMBOL(drm_ht_just_insert_please);
int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key,
struct drm_hash_item **item) struct drm_hash_item **item)
...@@ -169,6 +171,7 @@ int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, ...@@ -169,6 +171,7 @@ int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key,
*item = hlist_entry(list, struct drm_hash_item, head); *item = hlist_entry(list, struct drm_hash_item, head);
return 0; return 0;
} }
EXPORT_SYMBOL(drm_ht_find_item);
int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key) int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key)
{ {
...@@ -202,3 +205,4 @@ void drm_ht_remove(struct drm_open_hash *ht) ...@@ -202,3 +205,4 @@ void drm_ht_remove(struct drm_open_hash *ht)
ht->table = NULL; ht->table = NULL;
} }
} }
EXPORT_SYMBOL(drm_ht_remove);
...@@ -42,8 +42,11 @@ ...@@ -42,8 +42,11 @@
*/ */
#include "drmP.h" #include "drmP.h"
#include "drm_mm.h"
#include <linux/slab.h> #include <linux/slab.h>
#define MM_UNUSED_TARGET 4
unsigned long drm_mm_tail_space(struct drm_mm *mm) unsigned long drm_mm_tail_space(struct drm_mm *mm)
{ {
struct list_head *tail_node; struct list_head *tail_node;
...@@ -74,16 +77,62 @@ int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) ...@@ -74,16 +77,62 @@ int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
return 0; return 0;
} }
static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
{
struct drm_mm_node *child;
if (atomic)
child = kmalloc(sizeof(*child), GFP_ATOMIC);
else
child = kmalloc(sizeof(*child), GFP_KERNEL);
if (unlikely(child == NULL)) {
spin_lock(&mm->unused_lock);
if (list_empty(&mm->unused_nodes))
child = NULL;
else {
child =
list_entry(mm->unused_nodes.next,
struct drm_mm_node, fl_entry);
list_del(&child->fl_entry);
--mm->num_unused;
}
spin_unlock(&mm->unused_lock);
}
return child;
}
int drm_mm_pre_get(struct drm_mm *mm)
{
struct drm_mm_node *node;
spin_lock(&mm->unused_lock);
while (mm->num_unused < MM_UNUSED_TARGET) {
spin_unlock(&mm->unused_lock);
node = kmalloc(sizeof(*node), GFP_KERNEL);
spin_lock(&mm->unused_lock);
if (unlikely(node == NULL)) {
int ret = (mm->num_unused < 2) ? -ENOMEM : 0;
spin_unlock(&mm->unused_lock);
return ret;
}
++mm->num_unused;
list_add_tail(&node->fl_entry, &mm->unused_nodes);
}
spin_unlock(&mm->unused_lock);
return 0;
}
EXPORT_SYMBOL(drm_mm_pre_get);
static int drm_mm_create_tail_node(struct drm_mm *mm, static int drm_mm_create_tail_node(struct drm_mm *mm,
unsigned long start, unsigned long start,
unsigned long size) unsigned long size, int atomic)
{ {
struct drm_mm_node *child; struct drm_mm_node *child;
child = (struct drm_mm_node *) child = drm_mm_kmalloc(mm, atomic);
drm_alloc(sizeof(*child), DRM_MEM_MM); if (unlikely(child == NULL))
if (!child)
return -ENOMEM; return -ENOMEM;
child->free = 1; child->free = 1;
...@@ -97,8 +146,7 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, ...@@ -97,8 +146,7 @@ static int drm_mm_create_tail_node(struct drm_mm *mm,
return 0; return 0;
} }
int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic)
int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size)
{ {
struct list_head *tail_node; struct list_head *tail_node;
struct drm_mm_node *entry; struct drm_mm_node *entry;
...@@ -106,20 +154,21 @@ int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size) ...@@ -106,20 +154,21 @@ int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size)
tail_node = mm->ml_entry.prev; tail_node = mm->ml_entry.prev;
entry = list_entry(tail_node, struct drm_mm_node, ml_entry); entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
if (!entry->free) { if (!entry->free) {
return drm_mm_create_tail_node(mm, entry->start + entry->size, size); return drm_mm_create_tail_node(mm, entry->start + entry->size,
size, atomic);
} }
entry->size += size; entry->size += size;
return 0; return 0;
} }
static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
unsigned long size) unsigned long size,
int atomic)
{ {
struct drm_mm_node *child; struct drm_mm_node *child;
child = (struct drm_mm_node *) child = drm_mm_kmalloc(parent->mm, atomic);
drm_alloc(sizeof(*child), DRM_MEM_MM); if (unlikely(child == NULL))
if (!child)
return NULL; return NULL;
INIT_LIST_HEAD(&child->fl_entry); INIT_LIST_HEAD(&child->fl_entry);
...@@ -151,8 +200,9 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, ...@@ -151,8 +200,9 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
tmp = parent->start % alignment; tmp = parent->start % alignment;
if (tmp) { if (tmp) {
align_splitoff = drm_mm_split_at_start(parent, alignment - tmp); align_splitoff =
if (!align_splitoff) drm_mm_split_at_start(parent, alignment - tmp, 0);
if (unlikely(align_splitoff == NULL))
return NULL; return NULL;
} }
...@@ -161,7 +211,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, ...@@ -161,7 +211,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
parent->free = 0; parent->free = 0;
return parent; return parent;
} else { } else {
child = drm_mm_split_at_start(parent, size); child = drm_mm_split_at_start(parent, size, 0);
} }
if (align_splitoff) if (align_splitoff)
...@@ -169,14 +219,49 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, ...@@ -169,14 +219,49 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
return child; return child;
} }
EXPORT_SYMBOL(drm_mm_get_block); EXPORT_SYMBOL(drm_mm_get_block);
struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
unsigned long size,
unsigned alignment)
{
struct drm_mm_node *align_splitoff = NULL;
struct drm_mm_node *child;
unsigned tmp = 0;
if (alignment)
tmp = parent->start % alignment;
if (tmp) {
align_splitoff =
drm_mm_split_at_start(parent, alignment - tmp, 1);
if (unlikely(align_splitoff == NULL))
return NULL;
}
if (parent->size == size) {
list_del_init(&parent->fl_entry);
parent->free = 0;
return parent;
} else {
child = drm_mm_split_at_start(parent, size, 1);
}
if (align_splitoff)
drm_mm_put_block(align_splitoff);
return child;
}
EXPORT_SYMBOL(drm_mm_get_block_atomic);
/* /*
* Put a block. Merge with the previous and / or next block if they are free. * Put a block. Merge with the previous and / or next block if they are free.
* Otherwise add to the free stack. * Otherwise add to the free stack.
*/ */
void drm_mm_put_block(struct drm_mm_node * cur) void drm_mm_put_block(struct drm_mm_node *cur)
{ {
struct drm_mm *mm = cur->mm; struct drm_mm *mm = cur->mm;
...@@ -188,21 +273,27 @@ void drm_mm_put_block(struct drm_mm_node * cur) ...@@ -188,21 +273,27 @@ void drm_mm_put_block(struct drm_mm_node * cur)
int merged = 0; int merged = 0;
if (cur_head->prev != root_head) { if (cur_head->prev != root_head) {
prev_node = list_entry(cur_head->prev, struct drm_mm_node, ml_entry); prev_node =
list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
if (prev_node->free) { if (prev_node->free) {
prev_node->size += cur->size; prev_node->size += cur->size;
merged = 1; merged = 1;
} }
} }
if (cur_head->next != root_head) { if (cur_head->next != root_head) {
next_node = list_entry(cur_head->next, struct drm_mm_node, ml_entry); next_node =
list_entry(cur_head->next, struct drm_mm_node, ml_entry);
if (next_node->free) { if (next_node->free) {
if (merged) { if (merged) {
prev_node->size += next_node->size; prev_node->size += next_node->size;
list_del(&next_node->ml_entry); list_del(&next_node->ml_entry);
list_del(&next_node->fl_entry); list_del(&next_node->fl_entry);
drm_free(next_node, sizeof(*next_node), if (mm->num_unused < MM_UNUSED_TARGET) {
DRM_MEM_MM); list_add(&next_node->fl_entry,
&mm->unused_nodes);
++mm->num_unused;
} else
kfree(next_node);
} else { } else {
next_node->size += cur->size; next_node->size += cur->size;
next_node->start = cur->start; next_node->start = cur->start;
...@@ -215,14 +306,19 @@ void drm_mm_put_block(struct drm_mm_node * cur) ...@@ -215,14 +306,19 @@ void drm_mm_put_block(struct drm_mm_node * cur)
list_add(&cur->fl_entry, &mm->fl_entry); list_add(&cur->fl_entry, &mm->fl_entry);
} else { } else {
list_del(&cur->ml_entry); list_del(&cur->ml_entry);
drm_free(cur, sizeof(*cur), DRM_MEM_MM); if (mm->num_unused < MM_UNUSED_TARGET) {
list_add(&cur->fl_entry, &mm->unused_nodes);
++mm->num_unused;
} else
kfree(cur);
} }
} }
EXPORT_SYMBOL(drm_mm_put_block); EXPORT_SYMBOL(drm_mm_put_block);
struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
unsigned long size, unsigned long size,
unsigned alignment, int best_match) unsigned alignment, int best_match)
{ {
struct list_head *list; struct list_head *list;
const struct list_head *free_stack = &mm->fl_entry; const struct list_head *free_stack = &mm->fl_entry;
...@@ -247,7 +343,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, ...@@ -247,7 +343,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
wasted += alignment - tmp; wasted += alignment - tmp;
} }
if (entry->size >= size + wasted) { if (entry->size >= size + wasted) {
if (!best_match) if (!best_match)
return entry; return entry;
...@@ -260,6 +355,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, ...@@ -260,6 +355,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
return best; return best;
} }
EXPORT_SYMBOL(drm_mm_search_free);
int drm_mm_clean(struct drm_mm * mm) int drm_mm_clean(struct drm_mm * mm)
{ {
...@@ -267,14 +363,17 @@ int drm_mm_clean(struct drm_mm * mm) ...@@ -267,14 +363,17 @@ int drm_mm_clean(struct drm_mm * mm)
return (head->next->next == head); return (head->next->next == head);
} }
EXPORT_SYMBOL(drm_mm_search_free); EXPORT_SYMBOL(drm_mm_clean);
int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
{ {
INIT_LIST_HEAD(&mm->ml_entry); INIT_LIST_HEAD(&mm->ml_entry);
INIT_LIST_HEAD(&mm->fl_entry); INIT_LIST_HEAD(&mm->fl_entry);
INIT_LIST_HEAD(&mm->unused_nodes);
mm->num_unused = 0;
spin_lock_init(&mm->unused_lock);
return drm_mm_create_tail_node(mm, start, size); return drm_mm_create_tail_node(mm, start, size, 0);
} }
EXPORT_SYMBOL(drm_mm_init); EXPORT_SYMBOL(drm_mm_init);
...@@ -282,6 +381,7 @@ void drm_mm_takedown(struct drm_mm * mm) ...@@ -282,6 +381,7 @@ void drm_mm_takedown(struct drm_mm * mm)
{ {