drm: split edid handling in get_edid & add_edid_mode
authorJerome Glisse <glisse@freedesktop.org>
Fri, 9 Nov 2007 14:47:24 +0000 (15:47 +0100)
committerJerome Glisse <glisse@freedesktop.org>
Fri, 9 Nov 2007 14:47:24 +0000 (15:47 +0100)
This way driver can get_edid in output status detection
(using all workaround which are in get_edid) and then provide
this edid data in get_mode callback of output.

linux-core/drm_crtc.h
linux-core/drm_edid.c
linux-core/intel_modes.c

index d97cd19..9dd00b3 100644 (file)
@@ -487,8 +487,9 @@ extern void drm_output_destroy(struct drm_output *output);
 extern bool drm_output_rename(struct drm_output *output, const char *name);
 extern void drm_fb_release(struct file *filp);
 
-extern int drm_add_edid_modes(struct drm_output *output,
-                       struct i2c_adapter *adapter);
+extern struct edid *drm_get_edid(struct drm_output *output,
+                                struct i2c_adapter *adapter);
+extern int drm_add_edid_modes(struct drm_output *output, struct edid *edid);
 extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode);
 extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode);
 extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
index d7d3939..b8eee1a 100644 (file)
@@ -427,41 +427,51 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
 }
 
 /**
- * drm_add_edid_modes - add modes from EDID data, if available
+ * drm_get_edid - get EDID data, if available
  * @output: output we're probing
  * @adapter: i2c adapter to use for DDC
  *
- * Poke the given output's i2c channel to grab EDID data if possible.  If we
- * get any, add the specified modes to the output's mode list.
- *
- * Return number of modes added or 0 if we couldn't find any.
+ * Poke the given output's i2c channel to grab EDID data if possible.
+ * 
+ * Return edid data or NULL if we couldn't find any.
  */
-int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter)
+struct edid *drm_get_edid(struct drm_output *output,
+                         struct i2c_adapter *adapter)
 {
        struct edid *edid;
-       int num_modes = 0;
 
        edid = (struct edid *)drm_ddc_read(adapter);
        if (!edid) {
                dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
                         output->name);
-               goto out_err;
+               return NULL;
        }
-
        if (!edid_valid(edid)) {
                dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
                         output->name);
-               goto out_err;
+               kfree(edid);
+               return NULL;
        }
+       return edid;
+}
+EXPORT_SYMBOL(drm_get_edid);
+
+/**
+ * drm_add_edid_modes - add modes from EDID data, if available
+ * @output: output we're probing
+ * @edid: edid data
+ *
+ * Add the specified modes to the output's mode list.
+ *
+ * Return number of modes added or 0 if we couldn't find any.
+ */
+int drm_add_edid_modes(struct drm_output *output, struct edid *edid)
+{
+       int num_modes = 0;
 
        num_modes += add_established_modes(output, edid);
        num_modes += add_standard_modes(output, edid);
        num_modes += add_detailed_info(output, edid);
-
        return num_modes;
-
-out_err:
-       kfree(edid);
-       return 0;
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
index 601770e..346cf1a 100644 (file)
@@ -50,6 +50,13 @@ bool intel_ddc_probe(struct drm_output *output)
 int intel_ddc_get_modes(struct drm_output *output)
 {
        struct intel_output *intel_output = output->driver_private;
+       struct edid *edid;
+       int ret = 0;
 
-       return drm_add_edid_modes(output, &intel_output->ddc_bus->adapter);
+       edid = drm_get_edid(output, &intel_output->ddc_bus->adapter);
+       if (edid) {
+               ret = drm_add_edid_modes(output, edid);
+               kfree(edid);
+       }
+       return ret;
 }