]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/libdrm.git/commitdiff
Added kernel part of hotplug ioctl
authorJakob Bornecrantz <jakob@tungstengraphics.com>
Thu, 7 Feb 2008 18:24:58 +0000 (19:24 +0100)
committerJakob Bornecrantz <jakob@tungstengraphics.com>
Thu, 7 Feb 2008 18:24:58 +0000 (19:24 +0100)
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_drv.c
shared-core/i915_irq.c

index 03e5ffe954ebc308351e1ff9184733d0ee92b954..55390a8254ce3d1f91badb940aa6cf118867f0cc 100644 (file)
@@ -770,6 +770,7 @@ void drm_mode_config_init(struct drm_device *dev)
        dev->mode_config.num_fb = 0;
        dev->mode_config.num_output = 0;
        dev->mode_config.num_crtc = 0;
+       dev->mode_config.hotplug_counter = 0;
 }
 EXPORT_SYMBOL(drm_mode_config_init);
 
@@ -1130,10 +1131,18 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
  * RETURNS:
  * Zero on success, errno on failure.
  */
-int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
+int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,
+                         bool connected)
 {
        int has_config = 0;
 
+       /* We might want to do something more here */
+       if (!connected) {
+               DRM_DEBUG("not connected\n");
+               dev->mode_config.hotplug_counter++;
+               return 0;
+       }
+
        if (output->crtc && output->crtc->desired_mode) {
                DRM_DEBUG("drm thinks that the output already has a config\n");
                has_config = 1;
@@ -1146,7 +1155,7 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
 
        if (!output->crtc || !output->crtc->desired_mode) {
                DRM_DEBUG("could not find a desired mode or crtc for output\n");
-               return 1;
+               goto out_err;
        }
 
        /* We should realy check if there is a fb using this crtc */
@@ -1161,10 +1170,25 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
 
        drm_disable_unused_functions(dev);
 
+       dev->mode_config.hotplug_counter++;
        return 0;
+
+out_err:
+       dev->mode_config.hotplug_counter++;
+       return 1;
 }
 EXPORT_SYMBOL(drm_hotplug_stage_two);
 
+int drm_mode_hotplug_ioctl(struct drm_device *dev,
+                          void *data, struct drm_file *file_priv)
+{
+       struct drm_mode_hotplug *arg = data;
+
+       arg->counter = dev->mode_config.hotplug_counter;
+
+       return 0;
+}
+
 /**
  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
  * @out: drm_mode_modeinfo struct to return to the user
index 3b22e886963b8490c3c16490d2c6cf2d50a4e6ab..db5fd34ce2392e2bbdc1b7b288a811ae47e3268e 100644 (file)
@@ -547,6 +547,9 @@ struct drm_mode_config {
        struct drm_property *dpms_property;
        struct drm_property *connector_type_property;
        struct drm_property *connector_num_property;
+
+       /* hotplug */
+       uint32_t hotplug_counter;
 };
 
 struct drm_output *drm_output_create(struct drm_device *dev,
@@ -603,7 +606,7 @@ extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
 extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
 extern bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
                       int x, int y);
-extern int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output);
+extern int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output, bool connected);
 
 extern int drm_output_attach_property(struct drm_output *output,
                                      struct drm_property *property, uint64_t init_val);
@@ -646,5 +649,8 @@ extern int drm_mode_getblob_ioctl(struct drm_device *dev,
                                  void *data, struct drm_file *file_priv);
 extern int drm_mode_output_property_set_ioctl(struct drm_device *dev,
                                              void *data, struct drm_file *file_priv);
+extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
+                                 void *data, struct drm_file *file_priv);
+
 #endif /* __DRM_CRTC_H__ */
 
index 927225f14f803bd6c595bba05bd13e4d417da1ab..5077f067e918554ec530dc99835f1e66b735c9e7 100644 (file)
@@ -135,7 +135,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY | DRM_CONTROL_ALLOW),
-
+       DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW),
 
        DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
                      DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
index 836a8c46d7c232fab6cff4fc2494ebc89d2cfb9a..5f6fa56d2c920475e8f8164e22b59a70b4f84aa6 100644 (file)
@@ -413,6 +413,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
 }
 
 #define HOTPLUG_CMD_CRT 1
+#define HOTPLUG_CMD_CRT_DIS 2
 #define HOTPLUG_CMD_SDVOB 4
 #define HOTPLUG_CMD_SDVOC 8
 
@@ -420,7 +421,7 @@ static struct drm_device *hotplug_dev;
 static int hotplug_cmd = 0;
 static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
 
-static void i915_hotplug_crt(struct drm_device *dev)
+static void i915_hotplug_crt(struct drm_device *dev, bool connected)
 {
        struct drm_output *output;
        struct intel_output *iout;
@@ -439,7 +440,7 @@ static void i915_hotplug_crt(struct drm_device *dev)
        if (iout == 0)
                goto unlock;
 
-       drm_hotplug_stage_two(dev, output);
+       drm_hotplug_stage_two(dev, output, connected);
 
 unlock:
        mutex_unlock(&dev->mode_config.mutex);
@@ -462,9 +463,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
        status = output->funcs->detect(output);
 
        if (status != output_status_connected)
-               DRM_DEBUG("disconnect or unkown we don't do anything then\n");
+               drm_hotplug_stage_two(dev, output, false);
        else
-               drm_hotplug_stage_two(dev, output);
+               drm_hotplug_stage_two(dev, output, true);
 
        /* wierd hw bug, sdvo stop sending interupts */
        intel_sdvo_set_hotplug(output, 1);
@@ -484,18 +485,22 @@ static void i915_hotplug_work_func(struct work_struct *work)
 {
        struct drm_device *dev = hotplug_dev;
        int crt;
+       int crtDis;
        int sdvoB;
        int sdvoC;
 
        spin_lock(&hotplug_lock);
        crt = hotplug_cmd & HOTPLUG_CMD_CRT;
+       crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS;
        sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB;
        sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC;
        hotplug_cmd = 0;
        spin_unlock(&hotplug_lock);
 
        if (crt)
-               i915_hotplug_crt(dev);
+               i915_hotplug_crt(dev, true);
+       if (crtDis)
+               i915_hotplug_crt(dev, false);
 
        if (sdvoB)
                i915_hotplug_sdvo(dev, 1);
@@ -524,7 +529,9 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
                        hotplug_cmd |= HOTPLUG_CMD_CRT;
                        spin_unlock(&hotplug_lock);
                } else {
-                       /* handle crt disconnects */
+                       spin_lock(&hotplug_lock);
+                       hotplug_cmd |= HOTPLUG_CMD_CRT_DIS;
+                       spin_unlock(&hotplug_lock);
                }
        }