---
 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/drivers/gpu/drm/drm_crtc_helper.c:90 @ 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
@ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c:1216 @ 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
@ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c:18 @
 #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)
@ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c:225 @ 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)
@ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c:396 @ 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
@ 2.6.33/drivers/gpu/drm/drm_crtc_helper.c:511 @ 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];