From 451023dc32d4542c21b52ad1692e6e01cb75b099 Mon Sep 17 00:00:00 2001
From: Jani Nikula <jani.nikula@intel.com>
Date: Wed, 15 Aug 2012 09:32:39 +0000
Subject: drm: remove the raw_edid field from struct drm_display_info
Git-commit: 451023dc32d4542c21b52ad1692e6e01cb75b099
Patch-mainline: v3.7-rc1

Neither the drm core nor any of the drivers really need the raw_edid field
of struct drm_display_info for anything. Instead of being useful, it
creates confusion about who is responsible for freeing the memory it points
to and setting the field to NULL afterwards, leading to memory leaks and
dangling pointers.

Remove the raw_edid field, and fix drivers as necessary.

Reported-by: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Acked-by: Michal Srb <msrb@suse.com>
---
 drivers/gpu/drm/drm_edid.c                    |    3 ---
 drivers/gpu/drm/drm_edid_load.c               |   23 +++++++++++++----------
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c       |    2 --
 drivers/gpu/drm/gma500/oaktrail_hdmi.c        |    1 -
 drivers/gpu/drm/gma500/psb_intel_sdvo.c       |    3 ---
 drivers/gpu/drm/i915/intel_dp.c               |    4 ----
 drivers/gpu/drm/i915/intel_hdmi.c             |    3 ---
 drivers/gpu/drm/i915/intel_modes.c            |    1 -
 drivers/gpu/drm/i915/intel_sdvo.c             |    3 ---
 drivers/gpu/drm/mgag200/mgag200_mode.c        |    1 -
 drivers/gpu/drm/udl/udl_connector.c           |    3 ---
 drivers/staging/omapdrm/omap_connector.c      |    5 +----
 include/drm/drm_crtc.h                        |    2 --
 15 files changed, 15 insertions(+), 56 deletions(-)

Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/drm_edid.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/drm_edid.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/drm_edid.c
@@ -403,10 +403,7 @@ struct edid *drm_get_edid(struct drm_con
 	if (drm_probe_ddc(adapter))
 		edid = (struct edid *)drm_do_get_edid(connector, adapter);
 
-	connector->display_info.raw_edid = (char *)edid;
-
 	return edid;
-
 }
 EXPORT_SYMBOL(drm_get_edid);
 
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/drm_edid_load.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/drm_edid_load.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/drm_edid_load.c
@@ -114,8 +114,8 @@ static u8 generic_edid[GENERIC_EDIDS][12
 	},
 };
 
-static int edid_load(struct drm_connector *connector, char *name,
-		     char *connector_name)
+static u8 *edid_load(struct drm_connector *connector, char *name,
+			char *connector_name)
 {
 	const struct firmware *fw;
 	struct platform_device *pdev;
@@ -205,7 +205,6 @@ static int edid_load(struct drm_connecto
 		edid = new_edid;
 	}
 
-	connector->display_info.raw_edid = edid;
 	DRM_INFO("Got %s EDID base block and %d extension%s from "
 	    "\"%s\" for connector \"%s\"\n", builtin ? "built-in" :
 	    "external", valid_extensions, valid_extensions == 1 ? "" : "s",
@@ -215,7 +214,10 @@ relfw_out:
 	release_firmware(fw);
 
 out:
-	return err;
+	if (err)
+		return ERR_PTR(err);
+
+	return edid;
 }
 
 int drm_load_edid_firmware(struct drm_connector *connector)
@@ -223,6 +225,7 @@ int drm_load_edid_firmware(struct drm_co
 	char *connector_name = drm_get_connector_name(connector);
 	char *edidname = edid_firmware, *last, *colon;
 	int ret;
+	struct edid *edid;
 
 	if (*edidname == '\0')
 		return 0;
@@ -240,13 +243,13 @@ int drm_load_edid_firmware(struct drm_co
 	if (*last == '\n')
 		*last = '\0';
 
-	ret = edid_load(connector, edidname, connector_name);
-	if (ret)
+	edid = (struct edid *) edid_load(connector, edidname, connector_name);
+	if (IS_ERR_OR_NULL(edid))
 		return 0;
 
-	drm_mode_connector_update_edid_property(connector,
-	    (struct edid *) connector->display_info.raw_edid);
+	drm_mode_connector_update_edid_property(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+	kfree(edid);
 
-	return drm_add_edid_modes(connector, (struct edid *)
-	    connector->display_info.raw_edid);
+	return ret;
 }
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_dp.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/i915/intel_dp.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_dp.c
@@ -2188,7 +2188,6 @@ intel_dp_get_edid_modes(struct drm_conne
 		ret = drm_add_edid_modes(connector, intel_dp->edid);
 		drm_edid_to_eld(connector,
 				intel_dp->edid);
-		connector->display_info.raw_edid = NULL;
 		return intel_dp->edid_mode_count;
 	}
 
@@ -2228,7 +2227,6 @@ intel_dp_detect(struct drm_connector *co
 		edid = intel_dp_get_edid(connector, &intel_dp->adapter);
 		if (edid) {
 			intel_dp->has_audio = drm_detect_monitor_audio(edid);
-			connector->display_info.raw_edid = NULL;
 			kfree(edid);
 		}
 	}
@@ -2293,8 +2291,6 @@ intel_dp_detect_audio(struct drm_connect
 	edid = intel_dp_get_edid(connector, &intel_dp->adapter);
 	if (edid) {
 		has_audio = drm_detect_monitor_audio(edid);
-
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_hdmi.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/i915/intel_hdmi.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_hdmi.c
@@ -737,7 +737,6 @@ intel_hdmi_detect(struct drm_connector *
 						drm_detect_hdmi_monitor(edid);
 			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		}
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
@@ -778,8 +777,6 @@ intel_hdmi_detect_audio(struct drm_conne
 	if (edid) {
 		if (edid->input & DRM_EDID_INPUT_DIGITAL)
 			has_audio = drm_detect_monitor_audio(edid);
-
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_modes.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/i915/intel_modes.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_modes.c
@@ -45,7 +45,6 @@ int intel_connector_update_modes(struct
 	drm_mode_connector_update_edid_property(connector, edid);
 	ret = drm_add_edid_modes(connector, edid);
 	drm_edid_to_eld(connector, edid);
-	connector->display_info.raw_edid = NULL;
 	kfree(edid);
 
 	return ret;
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_sdvo.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/i915/intel_sdvo.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1366,7 +1366,6 @@ intel_sdvo_tmds_sink_detect(struct drm_c
 			}
 		} else
 			status = connector_status_disconnected;
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
@@ -1440,7 +1439,6 @@ intel_sdvo_detect(struct drm_connector *
 			else
 				ret = connector_status_disconnected;
 
-			connector->display_info.raw_edid = NULL;
 			kfree(edid);
 		} else
 			ret = connector_status_connected;
@@ -1486,7 +1484,6 @@ static void intel_sdvo_get_ddc_modes(str
 			drm_add_edid_modes(connector, edid);
 		}
 
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 }
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/mgag200/mgag200_mode.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1399,7 +1399,6 @@ static int mga_vga_get_modes(struct drm_
 	if (edid) {
 		drm_mode_connector_update_edid_property(connector, edid);
 		ret = drm_add_edid_modes(connector, edid);
-		connector->display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 	return ret;
Index: linux-3.0-SLE11-SP3/drivers/gpu/drm/udl/udl_connector.c
===================================================================
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/udl/udl_connector.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/udl/udl_connector.c
@@ -57,11 +57,8 @@ static int udl_get_modes(struct drm_conn
 
 	edid = (struct edid *)udl_get_edid(udl);
 
-	connector->display_info.raw_edid = (char *)edid;
-
 	drm_mode_connector_update_edid_property(connector, edid);
 	ret = drm_add_edid_modes(connector, edid);
-	connector->display_info.raw_edid = NULL;
 	kfree(edid);
 	return ret;
 }
Index: linux-3.0-SLE11-SP3/include/drm/drm_crtc.h
===================================================================
--- linux-3.0-SLE11-SP3.orig/include/drm/drm_crtc.h
+++ linux-3.0-SLE11-SP3/include/drm/drm_crtc.h
@@ -215,8 +215,6 @@ struct drm_display_info {
 	u32 color_formats;
 
 	u8 cea_rev;
-
-	char *raw_edid; /* if any */
 };
 
 struct drm_framebuffer_funcs {
