]> xenbits.xensource.com Git - people/aperard/linux-chromebook.git/commitdiff
drm/exynos: Let drm handle edid allocations
authorSean Paul <seanpaul@chromium.org>
Tue, 20 Nov 2012 19:19:00 +0000 (14:19 -0500)
committerGerrit <chrome-bot@google.com>
Tue, 20 Nov 2012 22:47:01 +0000 (14:47 -0800)
There's no need to allocate edid twice and do a memcpy when drm helpers
exist to do just that. This patch cleans that interaction up, and
doesn't keep the edid hanging around in the connector.

BUG=chromium-os:36513
TEST=Tested on snow boot/hotplug/idle suspend/lid suspend

Change-Id: Ifb971a7a6c6ae66ce431b9a256886d9699adbd09
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/38406

drivers/gpu/drm/exynos/exynos_drm_connector.c
drivers/gpu/drm/exynos/exynos_drm_display.h
drivers/gpu/drm/exynos/exynos_hdmi.c

index 24065fe2b0be74b7bf1b519abd1e281098167c08..86349e1bdd1cbf03ba468b6803d4659c1c2cd1a7 100644 (file)
@@ -114,42 +114,33 @@ static int exynos_drm_connector_get_edid(struct drm_connector *connector)
 {
        struct exynos_drm_display *display = display_from_connector(connector);
        int ret;
-       void *edid;
+       struct edid *edid;
 
        if (!display->panel_ops->get_edid)
                return -EINVAL;
 
-       edid = kzalloc(MAX_EDID, GFP_KERNEL);
-       if (!edid) {
-               DRM_ERROR("failed to allocate edid\n");
-               return -ENOMEM;
-       }
-
-       ret = display->panel_ops->get_edid(display->panel_ctx,
-                       connector, edid, MAX_EDID);
-       if (ret) {
+       edid = display->panel_ops->get_edid(display->panel_ctx, connector);
+       if (IS_ERR_OR_NULL(edid)) {
+               ret = PTR_ERR(edid);
+               edid = NULL;
                DRM_ERROR("Panel operation get_edid failed %d\n", ret);
-               goto err;
+               goto out;
        }
 
        ret = drm_mode_connector_update_edid_property(connector, edid);
        if (ret) {
                DRM_ERROR("update edid property failed(%d)\n", ret);
-               goto err;
+               goto out;
        }
 
        ret = drm_add_edid_modes(connector, edid);
        if (ret < 0) {
                DRM_ERROR("Add edid modes failed %d\n", ret);
-               goto err;
+               goto out;
        }
 
-       kfree(connector->display_info.raw_edid);
-       connector->display_info.raw_edid = edid;
-
-       return ret;
-
-err:
+out:
+       connector->display_info.raw_edid = NULL;
        kfree(edid);
        return ret;
 }
index 8cc52836f316e0018bcd87dc66aa408c496cfc44..d4bf3b098a889977a3edfede36dacee924b9a199 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @subdrv_probe: Used to associate drm_dev with panel context
  * @is_connected: Returns true if the panel is connected
- * @get_edid: Fills in edid with mode data from the panel
+ * @get_edid: Returns an edid with mode data from the panel
  * @check_timing: Returns 0 if the given timing is valid for the panel
  * @power: Sets the panel's power to mode
  * @dpms: Same as power, but called in different places. Best to avoid it
@@ -32,8 +32,7 @@
 struct exynos_panel_ops {
        int (*subdrv_probe)(void *ctx, struct drm_device *drm_dev);
        bool (*is_connected)(void *ctx);
-       int (*get_edid)(void *ctx, struct drm_connector *connector,
-                       u8 *edid, int len);
+       struct edid *(*get_edid)(void *ctx, struct drm_connector *connector);
        int (*check_timing)(void *ctx, void *timing);
        int (*power)(void *ctx, int mode);
        int (*dpms)(void *ctx, int mode);
index 900d7e1f7beec2fd98817470273bb9cdb8aafa39..8be11bee65243f71422d4e82644344bae07d8c61 100644 (file)
@@ -888,34 +888,29 @@ static bool hdmi_is_connected(void *ctx)
        return true;
 }
 
-static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
-                               u8 *edid, int len)
+static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
 {
-       struct edid *raw_edid;
        struct hdmi_context *hdata = ctx;
+       struct edid *edid;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
        if (!hdata->ddc_port)
                return -ENODEV;
 
-       raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
-       if (raw_edid) {
-       /* TODO : Need to call this in exynos_drm_connector.c, do a drm_get_edid
+       edid = drm_get_edid(connector, hdata->ddc_port->adapter);
+       if (!edid)
+               return ERR_PTR(-ENODEV);
+
+       /*
+        * TODO : Need to call this in exynos_drm_connector.c, do a drm_get_edid
         * to get the edid and then call drm_detect_hdmi_monitor.
         */
-               hdata->has_hdmi_sink = drm_detect_hdmi_monitor(raw_edid);
-               hdata->has_hdmi_audio = drm_detect_monitor_audio(raw_edid);
-               memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
-                                       * EDID_LENGTH, len));
-               DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
-                       (hdata->has_hdmi_sink ? "hdmi monitor" : "dvi monitor"),
-                       raw_edid->width_cm, raw_edid->height_cm);
-       } else {
-               return -ENODEV;
-       }
+       hdata->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+       hdata->has_hdmi_audio = drm_detect_monitor_audio(edid);
+       DRM_DEBUG_KMS("%s monitor\n", hdata->has_hdmi_sink ? "hdmi" : "dvi");
 
-       return 0;
+       return edid;
 }
 
 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)