From 7c5cc4f63556e351e9e5980ed22accad410e3fdc Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Thu, 18 Mar 2010 10:03:50 +1000
Subject: [PATCH] drm: add support for multi-seat capability demonstration.

This is just a demo, it doesn't add any of the userspace interfaces
necessary for configuring multi-seat.

load drm module with gpgpu=1 option

this adds 3 render nodes, radeon then hardcodes the setup for my X1900
card so that one crtc + one DVI got to the first node, second crtc + one
DVI got to the second, and the third node has no output nodes at all.

aside changes include:
moving the dev_mapping to the minor node not per device - this means
in theory we could have a mapping range per node which might be cleaner
but may require pushing minor pointers further down.

no longer pushing inode down into drm_open_helper.
---
 drivers/gpu/drm/drm_crtc.c             |    1 +
 drivers/gpu/drm/drm_drv.c              |    2 +-
 drivers/gpu/drm/drm_fops.c             |   29 +++++++------
 drivers/gpu/drm/drm_stub.c             |   47 ++++++++++++++++++++-
 drivers/gpu/drm/drm_vm.c               |   16 +++++++
 drivers/gpu/drm/i915/i915_gem.c        |    4 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c  |    4 +-
 drivers/gpu/drm/radeon/radeon_kms.c    |   73 +++++++++++++++++++++++++++++++-
 drivers/gpu/drm/radeon/radeon_object.c |    4 +-
 drivers/gpu/drm/radeon/radeon_ttm.c    |    5 +-
 drivers/gpu/drm/ttm/ttm_bo.c           |    7 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c    |    5 +-
 include/drm/drmP.h                     |    7 ++-
 include/drm/drm_crtc.h                 |    1 +
 include/drm/drm_mem_util.h             |    3 +
 include/drm/ttm/ttm_bo_driver.h        |    3 +-
 16 files changed, 176 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d91fb8c..bc9ba0f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -897,6 +897,7 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
 	group->num_encoders = 0;
 	return 0;
 }
+EXPORT_SYMBOL(drm_mode_group_init);
 
 int drm_mode_group_init_legacy_group(struct drm_device *dev,
 				     struct drm_mode_group *group)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index f3c58e2..62e4a5d 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -227,7 +227,7 @@ int drm_lastclose(struct drm_device * dev)
 	    !drm_core_check_feature(dev, DRIVER_MODESET))
 		drm_dma_takedown(dev);
 
-	dev->dev_mapping = NULL;
+	//	dev->dev_mapping = NULL;
 	mutex_unlock(&dev->struct_mutex);
 
 	DRM_DEBUG("lastclose completed\n");
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 08d14df..a21f5ac 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -38,8 +38,8 @@
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
 
-static int drm_open_helper(struct inode *inode, struct file *filp,
-			   struct drm_device * dev);
+static int drm_open_helper(struct file *filp,
+			   struct drm_minor *minor);
 
 static int drm_setup(struct drm_device * dev)
 {
@@ -128,7 +128,7 @@ int drm_open(struct inode *inode, struct file *filp)
 	if (!(dev = minor->dev))
 		return -ENODEV;
 
-	retcode = drm_open_helper(inode, filp, dev);
+	retcode = drm_open_helper(filp, minor);
 	if (!retcode) {
 		atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
 		spin_lock(&dev->count_lock);
@@ -141,11 +141,11 @@ int drm_open(struct inode *inode, struct file *filp)
 	}
 out:
 	mutex_lock(&dev->struct_mutex);
-	if (minor->type == DRM_MINOR_LEGACY) {
-		BUG_ON((dev->dev_mapping != NULL) &&
-			(dev->dev_mapping != inode->i_mapping));
-		if (dev->dev_mapping == NULL)
-			dev->dev_mapping = inode->i_mapping;
+	if (minor->type == DRM_MINOR_LEGACY || minor->type == DRM_MINOR_RENDER) {
+		BUG_ON((minor->dev_mapping != NULL) &&
+			(minor->dev_mapping != inode->i_mapping));
+		if (minor->dev_mapping == NULL)
+			minor->dev_mapping = inode->i_mapping;
 	}
 	mutex_unlock(&dev->struct_mutex);
 
@@ -226,10 +226,10 @@ static int drm_cpu_valid(void)
  * Creates and initializes a drm_file structure for the file private data in \p
  * filp and add it into the double linked list in \p dev.
  */
-static int drm_open_helper(struct inode *inode, struct file *filp,
-			   struct drm_device * dev)
+static int drm_open_helper(struct file *filp,
+			   struct drm_minor *minor)
 {
-	int minor_id = iminor(inode);
+	struct drm_device *dev = minor->dev;
 	struct drm_file *priv;
 	int ret;
 
@@ -238,7 +238,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 	if (!drm_cpu_valid())
 		return -EINVAL;
 
-	DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);
+	DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor->index);
 
 	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -249,7 +249,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 	priv->filp = filp;
 	priv->uid = current_euid();
 	priv->pid = task_pid_nr(current);
-	priv->minor = idr_find(&drm_minors_idr, minor_id);
+	priv->minor = minor;
 	priv->ioctl_count = 0;
 	/* for compatibility root is always authenticated */
 	priv->authenticated = capable(CAP_SYS_ADMIN);
@@ -552,7 +552,8 @@ int drm_release(struct inode *inode, struct file *filp)
 	}
 
 	/* drop the reference held my the file priv */
-	drm_master_put(&file_priv->master);
+	if (file_priv->master)
+		drm_master_put(&file_priv->master);
 	file_priv->is_master = 0;
 	list_del(&file_priv->lhead);
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index ad73e14..22c6250 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -39,6 +39,9 @@
 unsigned int drm_debug = 0;	/* 1 to enable debug output */
 EXPORT_SYMBOL(drm_debug);
 
+unsigned int drm_gpgpu = 0;
+EXPORT_SYMBOL(drm_gpgpu);
+
 MODULE_AUTHOR(CORE_AUTHOR);
 MODULE_DESCRIPTION(CORE_DESC);
 MODULE_LICENSE("GPL and additional rights");
@@ -46,6 +49,9 @@ MODULE_PARM_DESC(debug, "Enable debug output");
 
 module_param_named(debug, drm_debug, int, 0600);
 
+MODULE_PARM_DESC(gpgpu, "Enable GPGPU render node by default");
+module_param_named(gpgpu, drm_gpgpu, int, 0400);
+
 struct idr drm_minors_idr;
 
 struct class *drm_class;
@@ -234,6 +240,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
 	INIT_LIST_HEAD(&dev->vmalist);
 	INIT_LIST_HEAD(&dev->maplist);
 	INIT_LIST_HEAD(&dev->vblank_event_list);
+	INIT_LIST_HEAD(&dev->render_minor_list);
 
 	spin_lock_init(&dev->count_lock);
 	spin_lock_init(&dev->drw_lock);
@@ -343,6 +350,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
 	new_minor->dev = dev;
 	new_minor->index = minor_id;
 	INIT_LIST_HEAD(&new_minor->master_list);
+	INIT_LIST_HEAD(&new_minor->render_node_list);
 
 	idr_replace(&drm_minors_idr, new_minor, minor_id);
 
@@ -386,6 +394,29 @@ err_idr:
 	return ret;
 }
 
+int drm_create_minor_render(struct drm_device *dev, struct drm_minor **minor_p)
+{
+	int ret;
+	struct drm_minor *minor;
+
+	ret = drm_get_minor(dev, &minor, DRM_MINOR_RENDER);
+	if (ret)
+		return ret;
+
+	list_add_tail(&minor->render_node_list, &dev->render_minor_list);
+	return 0;
+}
+
+int drm_destroy_minor_render(struct drm_device *dev)
+{
+	struct drm_minor *minor, *tmp;
+
+	list_for_each_entry_safe(minor, tmp, &dev->render_minor_list, render_node_list) {
+		drm_put_minor(&minor);
+	}
+	return 0;
+}
+			    
 /**
  * Register.
  *
@@ -424,6 +455,15 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 		ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
 		if (ret)
 			goto err_g2;
+
+		if (drm_gpgpu) {
+			int i;
+			for (i = 0; i < 3; i++) {
+				struct drm_minor *test_minor;
+
+				drm_create_minor_render(dev, &test_minor);
+			}
+		}
 	}
 
 	if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
@@ -479,6 +519,8 @@ int drm_put_minor(struct drm_minor **minor_p)
 
 	DRM_DEBUG("release secondary minor %d\n", minor->index);
 
+	list_del(&minor->render_node_list);
+
 	if (minor->type == DRM_MINOR_LEGACY)
 		drm_proc_cleanup(minor, drm_proc_root);
 #if defined(CONFIG_DEBUG_FS)
@@ -542,9 +584,12 @@ void drm_put_dev(struct drm_device *dev)
 
 	drm_ctxbitmap_cleanup(dev);
 
-	if (drm_core_check_feature(dev, DRIVER_MODESET))
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		drm_put_minor(&dev->control);
 
+		drm_destroy_minor_render(dev);
+	}
+
 	if (driver->driver_features & DRIVER_GEM)
 		drm_gem_destroy(dev);
 
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 4ac900f..13d9e2b 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -676,3 +676,19 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
 	return ret;
 }
 EXPORT_SYMBOL(drm_mmap);
+
+void drm_unmap_mapping(struct drm_device *dev, loff_t const holebegin,
+		       loff_t const holelen)
+{
+	struct drm_minor *minor;
+	if (dev->primary->dev_mapping)
+		unmap_mapping_range(dev->primary->dev_mapping,
+				    holebegin, holelen, 1);
+
+	list_for_each_entry(minor, &dev->render_minor_list, render_node_list) {
+		if (minor->dev_mapping)
+			unmap_mapping_range(minor->dev_mapping,
+					    holebegin, holelen, 1);
+	}
+}
+EXPORT_SYMBOL(drm_unmap_mapping);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fba37e9..5c9de6f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1306,9 +1306,7 @@ i915_gem_release_mmap(struct drm_gem_object *obj)
 	struct drm_device *dev = obj->dev;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 
-	if (dev->dev_mapping)
-		unmap_mapping_range(dev->dev_mapping,
-				    obj_priv->mmap_offset, obj->size, 1);
+	drm_unmap_mapping(dev, obj_priv->mmap_offset, obj->size);
 }
 
 static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 0d22f66..5934201 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -136,8 +136,8 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
 
 	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
 
-	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
-		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
+	if (unlikely(dev_priv->ttm.bdev.mapping_priv == NULL))
+		dev_priv->ttm.bdev.mapping_priv = (void *)dev;
 
 	if (req->channel_hint) {
 		NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint,
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 20ec276..22e125a 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -31,7 +31,7 @@
 #include "radeon_drm.h"
 
 #include <linux/vga_switcheroo.h>
-
+extern int drm_gpgpu;
 int radeon_driver_unload_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
@@ -45,6 +45,72 @@ int radeon_driver_unload_kms(struct drm_device *dev)
 	return 0;
 }
 
+static int radeon_init_render_nodes(struct drm_device *dev)
+{
+	struct drm_minor *minor;
+	struct drm_connector *connector;
+	struct drm_crtc *crtc;
+	struct drm_mode_group *group;
+	int i = 0, j = 0;
+	int ret = 0;
+
+	list_for_each_entry(minor, &dev->render_minor_list, render_node_list) {
+		struct drm_connector *this_connector;
+
+		group = &minor->mode_group;
+		if (i == 2)
+			break;
+		/* initialise a mode group */
+		ret = drm_mode_group_init(dev, &minor->mode_group);
+		if (ret)
+			goto out;	
+		j = 0;
+		this_connector = NULL;
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			/* TODO de-hardcode */
+			if ((i == 0 && j == 0) || (i == 1 && j == 2)) {
+				this_connector = connector;
+				printk("pick connector %d for minor num %d\n", connector->base.id, i);
+				break;
+			}
+			j++;
+		}
+
+		if (!this_connector) {
+			printk("connector skip for %d\n", i);
+			goto next_one;
+		}
+
+		j = 0;
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			if (i == j) {
+				printk("pick crtc %d for minor num %d\n", crtc->base.id, i);
+				group->id_list[group->num_crtcs++] = crtc->base.id;
+				break;
+			}
+			j++;
+		}
+
+		for (j = 0; j < DRM_CONNECTOR_MAX_ENCODER; j++) {
+			if (this_connector->encoder_ids[j] != 0) 
+				group->id_list[group->num_crtcs + group->num_encoders++] = this_connector->encoder_ids[j];
+		}
+
+		group->id_list[group->num_crtcs + group->num_encoders + group->num_connectors++] = this_connector->base.id;
+
+	next_one:
+		printk("node %d %d %d %d", minor->index, group->num_crtcs, group->num_encoders, group->num_connectors);
+		for (j = 0; j < group->num_crtcs + group->num_encoders + group->num_connectors; j++)
+			printk("%d ", group->id_list[j]);
+		printk("\n");
+		i++;
+	}
+
+
+out:
+	return ret;
+}
+
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
 	struct radeon_device *rdev;
@@ -83,6 +149,11 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 	r = radeon_modeset_init(rdev);
 	if (r)
 		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+
+	/* assign group resources to the render minors */
+	if (drm_gpgpu) {
+		radeon_init_render_nodes(dev);
+	}
 out:
 	if (r)
 		radeon_driver_unload_kms(dev);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index fc9d00a..c0f5821 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -92,8 +92,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
 	enum ttm_bo_type type;
 	int r;
 
-	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
-		rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
+	if (unlikely(rdev->mman.bdev.mapping_priv == NULL)) {
+		rdev->mman.bdev.mapping_priv = (void *)rdev->ddev;
 	}
 	if (kernel) {
 		type = ttm_bo_type_kernel;
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 43c5ab3..2635048 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -529,8 +529,9 @@ int radeon_ttm_init(struct radeon_device *rdev)
 	}
 	DRM_INFO("radeon: %uM of GTT memory ready.\n",
 		 (unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
-	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
-		rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
+
+	if (unlikely(rdev->mman.bdev.mapping_priv == NULL)) {
+		rdev->mman.bdev.mapping_priv = (void *)rdev->ddev;
 	}
 
 	r = radeon_ttm_debugfs_init(rdev);
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 9db02bb..a97962e 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -45,6 +45,7 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/module.h>
+#include "drm/drm_mem_util.h"
 
 #define TTM_ASSERT_LOCKED(param)
 #define TTM_DEBUG(fmt, arg...)
@@ -1516,7 +1517,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev,
 	INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
 	bdev->nice_mode = true;
 	INIT_LIST_HEAD(&bdev->ddestroy);
-	bdev->dev_mapping = NULL;
+	bdev->mapping_priv = NULL;
 	bdev->glob = glob;
 	bdev->need_dma32 = need_dma32;
 
@@ -1579,10 +1580,10 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)
 	loff_t offset = (loff_t) bo->addr_space_offset;
 	loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
 
-	if (!bdev->dev_mapping)
+	if (!bdev->mapping_priv)
 		return;
 
-	unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1);
+	drm_unmap_mapping(bdev->mapping_priv, offset, holelen);
 }
 EXPORT_SYMBOL(ttm_bo_unmap_virtual);
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 0c9c081..b290191 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -461,9 +461,8 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
 
 	file_priv->driver_priv = vmw_fp;
 
-	if (unlikely(dev_priv->bdev.dev_mapping == NULL))
-		dev_priv->bdev.dev_mapping =
-			file_priv->filp->f_path.dentry->d_inode->i_mapping;
+	if (unlikely(dev_priv->bdev.mapping_priv == NULL))
+		dev_priv->bdev.mapping_priv = (void *)dev;
 
 	return 0;
 
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index de2f82e..13c1efb 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -891,6 +891,10 @@ struct drm_minor {
 	struct drm_master *master; /* currently active master for this node */
 	struct list_head master_list;
 	struct drm_mode_group mode_group;
+
+	struct address_space *dev_mapping;
+
+	struct list_head render_node_list;
 };
 
 struct drm_pending_vblank_event {
@@ -1024,7 +1028,6 @@ struct drm_device {
 	int num_crtcs;                  /**< Number of CRTCs on this device */
 	void *dev_private;		/**< device private data */
 	void *mm_private;
-	struct address_space *dev_mapping;
 	struct drm_sigdata sigdata;	   /**< For block_all_signals */
 	sigset_t sigmask;
 
@@ -1033,7 +1036,7 @@ struct drm_device {
 	unsigned int agp_buffer_token;
 	struct drm_minor *control;		/**< Control node for card */
 	struct drm_minor *primary;		/**< render type primary screen head */
-
+	struct list_head render_minor_list;
 	/** \name Drawable information */
 	/*@{ */
 	spinlock_t drw_lock;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1347524..d93d784 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -663,6 +663,7 @@ extern char *drm_get_dvi_i_select_name(int val);
 extern char *drm_get_tv_subconnector_name(int val);
 extern char *drm_get_tv_select_name(int val);
 extern void drm_fb_release(struct drm_file *file_priv);
+extern int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group);
 extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
 extern struct edid *drm_get_edid(struct drm_connector *connector,
 				 struct i2c_adapter *adapter);
diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h
index 6bd325f..820afbb 100644
--- a/include/drm/drm_mem_util.h
+++ b/include/drm/drm_mem_util.h
@@ -62,4 +62,7 @@ static __inline void drm_free_large(void *ptr)
 	vfree(ptr);
 }
 
+struct drm_device;
+extern void drm_unmap_mapping(struct drm_device *dev, loff_t const holebegin,
+			      loff_t const holelen);
 #endif
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index e929c27..755cd61 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -38,6 +38,7 @@
 #include "linux/fs.h"
 #include "linux/spinlock.h"
 
+struct drm_device;
 struct ttm_backend;
 
 struct ttm_backend_func {
@@ -464,7 +465,7 @@ struct ttm_bo_device {
 	 */
 
 	bool nice_mode;
-	struct address_space *dev_mapping;
+	struct drm_device *mapping_priv;
 
 	/*
 	 * Internal protection.
-- 
1.6.5.2

