--- /dev/null
+From 0f1cb1bd94a9c967cd4ad3de51cfdabe61eb5dcc Mon Sep 17 00:00:00 2001
+From: Ilija Hadzic <ilijahadzic@gmail.com>
+Date: Mon, 29 Oct 2012 17:35:00 +0000
+Subject: drm: restore open_count if drm_setup fails
+
+From: Ilija Hadzic <ilijahadzic@gmail.com>
+
+commit 0f1cb1bd94a9c967cd4ad3de51cfdabe61eb5dcc upstream.
+
+If drm_setup (called at first open) fails, the whole
+open call has failed, so we should not keep the
+open_count incremented.
+
+Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_fops.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -135,8 +135,11 @@ int drm_open(struct inode *inode, struct
+ retcode = drm_open_helper(inode, filp, dev);
+ if (!retcode) {
+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+- if (!dev->open_count++)
++ if (!dev->open_count++) {
+ retcode = drm_setup(dev);
++ if (retcode)
++ dev->open_count--;
++ }
+ }
+ if (!retcode) {
+ mutex_lock(&dev->struct_mutex);
--- /dev/null
+From fdb40a08ef7bc970899c3a1f471165f9c22763a1 Mon Sep 17 00:00:00 2001
+From: Ilija Hadzic <ilijahadzic@gmail.com>
+Date: Mon, 29 Oct 2012 17:35:01 +0000
+Subject: drm: set dev_mapping before calling drm_open_helper
+
+From: Ilija Hadzic <ilijahadzic@gmail.com>
+
+commit fdb40a08ef7bc970899c3a1f471165f9c22763a1 upstream.
+
+Some drivers (specifically vmwgfx) look at dev_mapping
+in their open hook, so we have to set dev->dev_mapping
+earlier in the process.
+
+Reference:
+http://lists.freedesktop.org/archives/dri-devel/2012-October/029420.html
+
+Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
+Reported-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_fops.c | 47 ++++++++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 17 deletions(-)
+
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct
+ int minor_id = iminor(inode);
+ struct drm_minor *minor;
+ int retcode = 0;
++ int need_setup = 0;
++ struct address_space *old_mapping;
+
+ minor = idr_find(&drm_minors_idr, minor_id);
+ if (!minor)
+@@ -132,26 +134,37 @@ int drm_open(struct inode *inode, struct
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
++ if (!dev->open_count++)
++ need_setup = 1;
++ mutex_lock(&dev->struct_mutex);
++ old_mapping = dev->dev_mapping;
++ if (old_mapping == NULL)
++ dev->dev_mapping = &inode->i_data;
++ /* ihold ensures nobody can remove inode with our i_data */
++ ihold(container_of(dev->dev_mapping, struct inode, i_data));
++ inode->i_mapping = dev->dev_mapping;
++ filp->f_mapping = dev->dev_mapping;
++ mutex_unlock(&dev->struct_mutex);
++
+ retcode = drm_open_helper(inode, filp, dev);
+- if (!retcode) {
+- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+- if (!dev->open_count++) {
+- retcode = drm_setup(dev);
+- if (retcode)
+- dev->open_count--;
+- }
+- }
+- if (!retcode) {
+- mutex_lock(&dev->struct_mutex);
+- if (dev->dev_mapping == NULL)
+- dev->dev_mapping = &inode->i_data;
+- /* ihold ensures nobody can remove inode with our i_data */
+- ihold(container_of(dev->dev_mapping, struct inode, i_data));
+- inode->i_mapping = dev->dev_mapping;
+- filp->f_mapping = dev->dev_mapping;
+- mutex_unlock(&dev->struct_mutex);
++ if (retcode)
++ goto err_undo;
++ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
++ if (need_setup) {
++ retcode = drm_setup(dev);
++ if (retcode)
++ goto err_undo;
+ }
++ return 0;
+
++err_undo:
++ mutex_lock(&dev->struct_mutex);
++ filp->f_mapping = old_mapping;
++ inode->i_mapping = old_mapping;
++ iput(container_of(dev->dev_mapping, struct inode, i_data));
++ dev->dev_mapping = old_mapping;
++ mutex_unlock(&dev->struct_mutex);
++ dev->open_count--;
+ return retcode;
+ }
+ EXPORT_SYMBOL(drm_open);