drm/omap: hdmi: Allocate EDID in the .read_edid() operation
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Wed, 26 Feb 2020 11:24:48 +0000 (13:24 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 26 Feb 2020 11:31:52 +0000 (13:31 +0200)
Bring the omapdss-specific .read_edid() operation in sync with the
drm_bridge .get_edid() operation to ease code reuse.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200226112514.12455-29-laurent.pinchart@ideasonboard.com
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/omapdss.h
drivers/gpu/drm/omapdrm/omap_connector.c

index dd4a14f..e15fa38 100644 (file)
@@ -405,31 +405,45 @@ static void hdmi_disconnect(struct omap_dss_device *src,
        omapdss_device_disconnect(dst, dst->next);
 }
 
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
-               u8 *edid, int len)
+#define MAX_EDID       512
+
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
        bool need_enable;
+       u8 *edid;
        int r;
 
+       edid = kzalloc(MAX_EDID, GFP_KERNEL);
+       if (!edid)
+               return NULL;
+
        need_enable = hdmi->core_enabled == false;
 
        if (need_enable) {
                r = hdmi4_core_enable(&hdmi->core);
-               if (r)
-                       return r;
+               if (r) {
+                       kfree(edid);
+                       return NULL;
+               }
+       }
+
+       r = read_edid(hdmi, edid, MAX_EDID);
+       if (r < 0) {
+               kfree(edid);
+               edid = NULL;
+       } else {
+               unsigned int cec_addr;
+
+               cec_addr = r >= 256 ? cec_get_edid_phys_addr(edid, r, NULL)
+                        : CEC_PHYS_ADDR_INVALID;
+               hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
        }
 
-       r = read_edid(hdmi, edid, len);
-       if (r >= 256)
-               hdmi4_cec_set_phys_addr(&hdmi->core,
-                                       cec_get_edid_phys_addr(edid, r, NULL));
-       else
-               hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
        if (need_enable)
                hdmi4_core_disable(&hdmi->core);
 
-       return r;
+       return (struct edid *)edid;
 }
 
 static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
index 8e3790d..99720df 100644 (file)
@@ -410,27 +410,39 @@ static void hdmi_disconnect(struct omap_dss_device *src,
        omapdss_device_disconnect(dst, dst->next);
 }
 
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
-               u8 *edid, int len)
+#define MAX_EDID       512
+
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
        bool need_enable;
+       u8 *edid;
        int r;
 
+       edid = kzalloc(MAX_EDID, GFP_KERNEL);
+       if (!edid)
+               return NULL;
+
        need_enable = hdmi->core_enabled == false;
 
        if (need_enable) {
                r = hdmi_core_enable(hdmi);
-               if (r)
-                       return r;
+               if (r) {
+                       kfree(edid);
+                       return NULL;
+               }
        }
 
-       r = read_edid(hdmi, edid, len);
+       r = read_edid(hdmi, edid, MAX_EDID);
+       if (r < 0) {
+               kfree(edid);
+               edid = NULL;
+       }
 
        if (need_enable)
                hdmi_core_disable(hdmi);
 
-       return r;
+       return (struct edid *)edid;
 }
 
 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
index 82e9bfa..269e143 100644 (file)
@@ -367,7 +367,7 @@ struct omap_dss_device_ops {
                                void *cb_data);
        void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
 
-       int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
+       struct edid *(*read_edid)(struct omap_dss_device *dssdev);
 
        int (*get_modes)(struct omap_dss_device *dssdev,
                         struct drm_connector *connector);
index a24cec4..c636ae2 100644 (file)
@@ -153,25 +153,19 @@ static void omap_connector_destroy(struct drm_connector *connector)
        kfree(omap_connector);
 }
 
-#define MAX_EDID  512
-
 static int omap_connector_get_modes_edid(struct drm_connector *connector,
                                         struct omap_dss_device *dssdev)
 {
        enum drm_connector_status status;
-       void *edid;
+       struct edid *edid;
        int n;
 
        status = omap_connector_detect(connector, false);
        if (status != connector_status_connected)
                goto no_edid;
 
-       edid = kzalloc(MAX_EDID, GFP_KERNEL);
-       if (!edid)
-               goto no_edid;
-
-       if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 ||
-           !drm_edid_is_valid(edid)) {
+       edid = dssdev->ops->read_edid(dssdev);
+       if (!edid || !drm_edid_is_valid(edid)) {
                kfree(edid);
                goto no_edid;
        }