memset(&set, 0, sizeof(struct drm_mode_set));
                        set.crtc = crtc;
                        set.fb = NULL;
-                       ret = crtc->funcs->set_config(&set);
+                       ret = drm_mode_set_config_internal(&set);
                        if (ret)
                                DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
                }
        return ret;
 }
 
+/**
+ * drm_mode_set_config_internal - helper to call ->set_config
+ * @set: modeset config to set
+ *
+ * This is a little helper to wrap internal calls to the ->set_config driver
+ * interface. The only thing it adds is correct refcounting dance.
+ */
+int drm_mode_set_config_internal(struct drm_mode_set *set)
+{
+       struct drm_crtc *crtc = set->crtc;
+
+       return crtc->funcs->set_config(set);
+}
+EXPORT_SYMBOL(drm_mode_set_config_internal);
+
 /**
  * drm_mode_setcrtc - set CRTC configuration
  * @dev: drm device for the ioctl
        set.connectors = connector_set;
        set.num_connectors = crtc_req->count_connectors;
        set.fb = fb;
-       ret = crtc->funcs->set_config(&set);
+       ret = drm_mode_set_config_internal(&set);
 
 out:
        kfree(connector_set);
 
        int i, ret;
        for (i = 0; i < fb_helper->crtc_count; i++) {
                struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
-               ret = mode_set->crtc->funcs->set_config(mode_set);
+               ret = drm_mode_set_config_internal(mode_set);
                if (ret)
                        error = true;
        }
        mutex_lock(&dev->mode_config.mutex);
        for (i = 0; i < fb_helper->crtc_count; i++) {
                crtc = fb_helper->crtc_info[i].mode_set.crtc;
-               ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
+               ret = drm_mode_set_config_internal(&fb_helper->crtc_info[i].mode_set);
                if (ret) {
                        mutex_unlock(&dev->mode_config.mutex);
                        return ret;
                modeset->y = var->yoffset;
 
                if (modeset->num_connectors) {
-                       ret = crtc->funcs->set_config(modeset);
+                       ret = drm_mode_set_config_internal(modeset);
                        if (!ret) {
                                info->var.xoffset = var->xoffset;
                                info->var.yoffset = var->yoffset;
 
                                .crtc = crtc,
                        };
 
-                       crtc->funcs->set_config(&modeset);
+                       drm_mode_set_config_internal(&modeset);
                }
        }
 
 
                        .crtc = crtc,
                };
 
-               crtc->funcs->set_config(&modeset);
+               drm_mode_set_config_internal(&modeset);
        }
 
        /* Restore state */
 
                                .crtc = crtc,
                        };
 
-                       crtc->funcs->set_config(&modeset);
+                       drm_mode_set_config_internal(&modeset);
                }
        }
 
 
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                set.crtc = crtc;
-               ret = crtc->funcs->set_config(&set);
+               ret = drm_mode_set_config_internal(&set);
                WARN_ON(ret != 0);
        }
 
 
                            void *data, struct drm_file *file_priv);
 extern int drm_mode_getconnector(struct drm_device *dev,
                              void *data, struct drm_file *file_priv);
+extern int drm_mode_set_config_internal(struct drm_mode_set *set);
 extern int drm_mode_setcrtc(struct drm_device *dev,
                            void *data, struct drm_file *file_priv);
 extern int drm_mode_getplane(struct drm_device *dev,