The rest of the DRM framework uses presence of the callbacks to check if
the particular infoframe is supported. Register HDMI callbacks
dynamically, basing on the corresponding drm_bridge ops.

Signed-off-by: Dmitry Baryshkov <[email protected]>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 94 ++++++++++++--------------
 1 file changed, 45 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c 
b/drivers/gpu/drm/display/drm_bridge_connector.c
index c8858d48199c..2a8f586c6d13 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -123,6 +123,14 @@ struct drm_bridge_connector {
         * DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER).
         */
        struct drm_bridge *bridge_hdmi_cec;
+
+       /**
+        * @hdmi_funcs:
+        *
+        * The particular &drm_connector_hdmi_funcs implementation for this
+        * bridge connector.
+        */
+       struct drm_connector_hdmi_funcs hdmi_funcs;
 };
 
 #define to_drm_bridge_connector(x) \
@@ -465,12 +473,7 @@ static int 
drm_bridge_connector_clear_audio_infoframe(struct drm_connector *conn
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO)
-               return bridge->funcs->hdmi_clear_audio_infoframe(bridge);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_clear_audio_infoframe(bridge);
 }
 
 static int drm_bridge_connector_write_audio_infoframe(struct drm_connector 
*connector,
@@ -484,12 +487,7 @@ static int 
drm_bridge_connector_write_audio_infoframe(struct drm_connector *conn
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO)
-               return bridge->funcs->hdmi_write_audio_infoframe(bridge, 
buffer, len);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len);
 }
 
 static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector 
*connector)
@@ -502,12 +500,7 @@ static int 
drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *co
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
-               return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge);
 }
 
 static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector 
*connector,
@@ -521,12 +514,7 @@ static int 
drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *co
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
-               return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, 
buffer, len);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len);
 }
 
 static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector 
*connector)
@@ -539,12 +527,7 @@ static int drm_bridge_connector_clear_spd_infoframe(struct 
drm_connector *connec
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
-               return bridge->funcs->hdmi_clear_spd_infoframe(bridge);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_clear_spd_infoframe(bridge);
 }
 
 static int drm_bridge_connector_write_spd_infoframe(struct drm_connector 
*connector,
@@ -558,12 +541,7 @@ static int drm_bridge_connector_write_spd_infoframe(struct 
drm_connector *connec
        if (!bridge)
                return -EINVAL;
 
-       if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
-               return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, 
len);
-
-       drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n");
-
-       return 0;
+       return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
 }
 
 static const struct drm_edid *
@@ -591,18 +569,22 @@ static const struct drm_connector_hdmi_funcs 
drm_bridge_connector_hdmi_funcs = {
                .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe,
                .write_infoframe = drm_bridge_connector_write_hdmi_infoframe,
        },
-       .audio = {
-               .clear_infoframe = drm_bridge_connector_clear_audio_infoframe,
-               .write_infoframe = drm_bridge_connector_write_audio_infoframe,
-       },
-       .hdr_drm = {
-               .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe,
-               .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe,
-       },
-       .spd = {
-               .clear_infoframe = drm_bridge_connector_clear_spd_infoframe,
-               .write_infoframe = drm_bridge_connector_write_spd_infoframe,
-       },
+       /* audio, hdr_drm and spd are set dynamically during init */
+};
+
+static const struct drm_connector_infoframe_funcs 
drm_bridge_connector_hdmi_audio_infoframe = {
+       .clear_infoframe = drm_bridge_connector_clear_audio_infoframe,
+       .write_infoframe = drm_bridge_connector_write_audio_infoframe,
+};
+
+static const struct drm_connector_infoframe_funcs 
drm_bridge_connector_hdmi_hdr_drm_infoframe = {
+       .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe,
+       .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe,
+};
+
+static const struct drm_connector_infoframe_funcs 
drm_bridge_connector_hdmi_spd_infoframe = {
+       .clear_infoframe = drm_bridge_connector_clear_spd_infoframe,
+       .write_infoframe = drm_bridge_connector_write_spd_infoframe,
 };
 
 static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
@@ -971,11 +953,25 @@ struct drm_connector *drm_bridge_connector_init(struct 
drm_device *drm,
                if (!connector->ycbcr_420_allowed)
                        supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420);
 
+               bridge_connector->hdmi_funcs = drm_bridge_connector_hdmi_funcs;
+
+               if (bridge_connector->bridge_hdmi->ops & 
DRM_BRIDGE_OP_HDMI_AUDIO)
+                       bridge_connector->hdmi_funcs.audio =
+                               drm_bridge_connector_hdmi_audio_infoframe;
+
+               if (bridge_connector->bridge_hdmi->ops & 
DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
+                       bridge_connector->hdmi_funcs.hdr_drm =
+                               drm_bridge_connector_hdmi_hdr_drm_infoframe;
+
+               if (bridge_connector->bridge_hdmi->ops & 
DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
+                       bridge_connector->hdmi_funcs.spd =
+                               drm_bridge_connector_hdmi_spd_infoframe;
+
                ret = drmm_connector_hdmi_init(drm, connector,
                                               
bridge_connector->bridge_hdmi->vendor,
                                               
bridge_connector->bridge_hdmi->product,
                                               &drm_bridge_connector_funcs,
-                                              &drm_bridge_connector_hdmi_funcs,
+                                              &bridge_connector->hdmi_funcs,
                                               connector_type, ddc,
                                               supported_formats,
                                               max_bpc);

-- 
2.47.3

Reply via email to