summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_edid_load.c
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2012-08-15 11:32:39 +0200
committerDave Airlie <airlied@redhat.com>2012-08-24 01:37:36 +0200
commit451023dc32d4542c21b52ad1692e6e01cb75b099 (patch)
tree9380bd992f953d0a7403b3894bd1d946b6fbca91 /drivers/gpu/drm/drm_edid_load.c
parentdrm/ast: fix EDID memory leak (diff)
downloadlinux-451023dc32d4542c21b52ad1692e6e01cb75b099.tar.xz
linux-451023dc32d4542c21b52ad1692e6e01cb75b099.zip
drm: remove the raw_edid field from struct drm_display_info
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>
Diffstat (limited to 'drivers/gpu/drm/drm_edid_load.c')
-rw-r--r--drivers/gpu/drm/drm_edid_load.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 0303935d10e2..186832e1874e 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -114,8 +114,8 @@ static u8 generic_edid[GENERIC_EDIDS][128] = {
},
};
-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_connector *connector, char *name,
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_connector *connector)
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_connector *connector)
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;
}