drm: make fb modes use usermode add/remove interface
authorDave Airlie <airlied@redhat.com>
Mon, 26 Nov 2007 03:05:49 +0000 (14:05 +1100)
committerDave Airlie <airlied@redhat.com>
Mon, 26 Nov 2007 03:05:49 +0000 (14:05 +1100)
this stops usermode from getting a mode in the crtc it can't make sense off.

linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_drv.c
linux-core/intel_fb.c

index df93484..8730255 100644 (file)
@@ -439,7 +439,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
                if (output->crtc != crtc)
                        continue;
                
-               DRM_INFO("%s: set mode %s\n", output->name, mode->name);
+               DRM_INFO("%s: set mode %s %x\n", output->name, mode->name, mode->mode_id);
 
                output->funcs->mode_set(output, mode, adjusted_mode);
        }
@@ -858,7 +858,7 @@ clone:
                        output->crtc->desired_mode = des_mode;
                        output->initial_x = 0;
                        output->initial_y = 0;
-                       DRM_DEBUG("Desired mode for CRTC %d is %s\n",c,des_mode->name);
+                       DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
                        break;
                }
        }
@@ -1694,8 +1694,36 @@ void drm_fb_release(struct file *filp)
        mutex_unlock(&dev->mode_config.mutex);
 }
 
+/*
+ *
+ */
+void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode)
+{
+       user_mode->type |= DRM_MODE_TYPE_USERDEF;
+
+       user_mode->output_count = 0;
+       list_add(&user_mode->head, &dev->mode_config.usermode_list);
+}
+EXPORT_SYMBOL(drm_mode_addmode);
+
+int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode)
+{
+       struct drm_display_mode *t;
+       int ret = -EINVAL;
+       list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
+               if (t == mode) {
+                       list_del(&mode->head);
+                       drm_mode_destroy(dev, mode);
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+EXPORT_SYMBOL(drm_mode_rmmode);
+
 /**
- * drm_fb_newmode - adds a user defined mode
+ * drm_fb_addmode - adds a user defined mode
  * @inode: inode from the ioctl
  * @filp: file * from the ioctl
  * @cmd: cmd from ioctl
@@ -1709,8 +1737,8 @@ void drm_fb_release(struct file *filp)
  * writes new mode id into arg.
  * Zero on success, errno on failure.
  */
-int drm_mode_addmode(struct drm_device *dev,
-                    void *data, struct drm_file *file_priv)
+int drm_mode_addmode_ioctl(struct drm_device *dev,
+                          void *data, struct drm_file *file_priv)
 {
        struct drm_mode_modeinfo *new_mode = data;
        struct drm_display_mode *user_mode;
@@ -1724,12 +1752,8 @@ int drm_mode_addmode(struct drm_device *dev,
        }
 
        drm_crtc_convert_umode(user_mode, new_mode);
-       user_mode->type |= DRM_MODE_TYPE_USERDEF;
-
-       user_mode->output_count = 0;
-
-       list_add(&user_mode->head, &dev->mode_config.usermode_list);
 
+       drm_mode_addmode(dev, user_mode);
        new_mode->id = user_mode->mode_id;
 
 out:
@@ -1751,38 +1775,28 @@ out:
  * RETURNS:
  * Zero on success, errno on failure.
  */
-int drm_mode_rmmode(struct drm_device *dev,
-                   void *data, struct drm_file *file_priv)
+int drm_mode_rmmode_ioctl(struct drm_device *dev,
+                         void *data, struct drm_file *file_priv)
 {
        uint32_t *id = data;
-       struct drm_display_mode *mode, *t;
+       struct drm_display_mode *mode;
        int ret = -EINVAL;
 
        mutex_lock(&dev->mode_config.mutex);    
        mode = idr_find(&dev->mode_config.crtc_idr, *id);
        if (!mode || (*id != mode->mode_id)) {
-               ret = -EINVAL;
                goto out;
        }
 
        if (!(mode->type & DRM_MODE_TYPE_USERDEF)) {
-               ret = -EINVAL;
                goto out;
        }
 
        if (mode->output_count) {
-               ret = -EINVAL;
                goto out;
        }
 
-       list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
-               if (t == mode) {
-                       list_del(&mode->head);
-                       drm_mode_destroy(dev, mode);
-                       ret = 0;
-                       break;
-               }
-       }
+       ret = drm_mode_rmmode(dev, mode);
 
 out:
        mutex_unlock(&dev->mode_config.mutex);
index 0645dd6..f555b6b 100644 (file)
@@ -494,6 +494,9 @@ extern void drm_mode_set_name(struct drm_display_mode *mode);
 extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
 extern void drm_disable_unused_functions(struct drm_device *dev);
 
+extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode);
+extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode);
+
 extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
 extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
 extern void drm_mode_list_concat(struct list_head *head,
@@ -536,10 +539,10 @@ extern int drm_mode_rmfb(struct drm_device *dev,
                         void *data, struct drm_file *file_priv);
 extern int drm_mode_getfb(struct drm_device *dev,
                          void *data, struct drm_file *file_priv);
-extern int drm_mode_addmode(struct drm_device *dev,
-                           void *data, struct drm_file *file_priv);
-extern int drm_mode_rmmode(struct drm_device *dev,
-                          void *data, struct drm_file *file_priv);
+extern int drm_mode_addmode_ioctl(struct drm_device *dev,
+                                 void *data, struct drm_file *file_priv);
+extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
+                                void *data, struct drm_file *file_priv);
 extern int drm_mode_attachmode(struct drm_device *dev,
                               void *data, struct drm_file *file_priv);
 extern int drm_mode_detachmode(struct drm_device *dev,
index 8cd7afb..5156d15 100644 (file)
@@ -124,8 +124,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode, DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY),
 
index 564a913..3a4ffc7 100644 (file)
@@ -47,6 +47,7 @@
 struct intelfb_par {
        struct drm_device *dev;
        struct drm_crtc *crtc;
+        struct drm_display_mode *fb_mode;
 };
 
 static int
@@ -107,7 +108,6 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
         struct intelfb_par *par = info->par;
         struct drm_device *dev = par->dev;
        struct drm_framebuffer *fb = par->crtc->fb;
-        struct drm_display_mode *drm_mode;
         struct drm_output *output;
         int depth, found = 0;
 
@@ -275,6 +275,7 @@ static int intelfb_set_par(struct fb_info *info)
                return -EINVAL;
        }
 #else
+       
         drm_mode = drm_mode_create(dev);
         drm_mode->hdisplay = var->xres;
         drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
@@ -290,18 +291,16 @@ static int intelfb_set_par(struct fb_info *info)
        drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
 #endif
 
+       drm_mode_addmode(dev, drm_mode);
+       if (par->fb_mode)
+               drm_mode_rmmode(dev, par->fb_mode);
+       
+       par->fb_mode = drm_mode;
        drm_mode_debug_printmodeline(dev, drm_mode);
 
         if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
                 return -EINVAL;
 
-        /* Have to destroy our created mode if we're not searching the mode
-         * list for it.
-         */
-#if 1
-        drm_mode_destroy(dev, drm_mode);
-#endif
-
        return 0;
 }