---
 drivers/gpu/drm/drm_crtc_helper.c |    7 ++++
 drivers/gpu/drm/drm_edid.c        |    5 +++
 drivers/gpu/drm/drm_sysfs.c       |   63 +++++++++++++++++++++++++++++++++++++-
 include/drm/drm_crtc.h            |    1 
 4 files changed, 75 insertions(+), 1 deletion(-)

Index: 2.6.33/drivers/gpu/drm/drm_crtc_helper.c
===================================================================
--- 2.6.33.orig/drivers/gpu/drm/drm_crtc_helper.c
+++ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c
@@ -87,6 +87,13 @@ int drm_helper_probe_single_connector_mo
        int mode_flags = 0;
 
        DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector));
+
+       if (connector->edid_pinned) {
+               list_for_each_entry(mode, &connector->modes, head)
+                       count++;
+               return count;
+       }
+
        /* set all modes to the unverified state */
        list_for_each_entry_safe(mode, t, &connector->modes, head)
                mode->status = MODE_UNVERIFIED;
Index: 2.6.33/drivers/gpu/drm/drm_edid.c
===================================================================
--- 2.6.33.orig/drivers/gpu/drm/drm_edid.c
+++ 2.6.33/drivers/gpu/drm/drm_edid.c
@@ -1213,6 +1213,11 @@ struct edid *drm_get_edid(struct drm_con
        int ret;
        struct edid *edid;
 
+       if (connector->edid_pinned) {
+               edid = (struct edid *) connector->display_info.raw_edid;
+               goto end;
+       }
+
        edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
                       GFP_KERNEL);
        if (edid == NULL) {
Index: 2.6.33/drivers/gpu/drm/drm_sysfs.c
===================================================================
--- 2.6.33.orig/drivers/gpu/drm/drm_sysfs.c
+++ 2.6.33/drivers/gpu/drm/drm_sysfs.c
@@ -15,9 +15,11 @@
 #include <linux/device.h>
 #include <linux/kdev_t.h>
 #include <linux/err.h>
+#include <linux/firmware.h>
 
 #include "drm_sysfs.h"
 #include "drm_core.h"
+#include "drm_edid.h"
 #include "drmP.h"
 
 #define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
@@ -220,6 +222,64 @@ static ssize_t edid_show(struct kobject 
        return count;
 }
 
+static ssize_t edid_store(struct kobject *kobj, struct bin_attribute *attr,
+                         char *buf, loff_t off, size_t count)
+{
+       struct device *connector_dev = container_of(kobj, struct device, kobj);
+       struct drm_connector *connector = to_drm_connector(connector_dev);
+       const struct firmware *fw;
+       unsigned char *edid;
+       size_t size = EDID_LENGTH;
+       int status;
+       char *filename, *cr;
+
+       if (count == 0 || *buf == '\n' || *buf == '\0') {
+               connector->edid_pinned = 0;
+               return count;
+       }
+
+       filename = kmalloc(count+1, GFP_KERNEL);
+       if (!filename)
+               return -ENOMEM;
+       memcpy(filename, buf, count);
+       filename[count] = '\0';
+
+       cr = strchr(filename, '\n');
+       if (cr)
+               *cr = '\0';
+
+        status = request_firmware(&fw, filename, connector_dev);
+       kfree(filename);
+        if (status)
+               return status;
+
+       if (fw->size != size) {
+               release_firmware(fw);
+               return -EINVAL;
+       }
+
+       edid = kmalloc(size, GFP_KERNEL);
+       if (edid == NULL) {
+               release_firmware(fw);
+               return -ENOMEM;
+       }
+
+        edid = (unsigned char *) fw->data;
+
+       drm_mode_connector_update_edid_property(connector,
+           (struct edid *) edid);
+       drm_add_edid_modes(connector, (struct edid *) edid);
+       drm_mode_connector_list_update(connector);
+       drm_mode_sort(&connector->modes);
+
+       connector->display_info.raw_edid = edid;
+       connector->edid_pinned = 1;
+
+       release_firmware(fw);
+
+       return count;
+}
+
 static ssize_t modes_show(struct device *device,
                           struct device_attribute *attr,
                           char *buf)
@@ -333,9 +393,10 @@ static struct device_attribute connector
 
 static struct bin_attribute edid_attr = {
        .attr.name = "edid",
-       .attr.mode = 0444,
+       .attr.mode = 0644,
        .size = 128,
        .read = edid_show,
+       .write = edid_store,
 };
 
 /**
Index: 2.6.33/include/drm/drm_crtc.h
===================================================================
--- 2.6.33.orig/include/drm/drm_crtc.h
+++ 2.6.33/include/drm/drm_crtc.h
@@ -508,6 +508,7 @@ struct drm_connector {
 
        struct list_head user_modes;
        struct drm_property_blob *edid_blob_ptr;
+       int edid_pinned;
        u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
        uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];