The common connector setup in msm_kms_init_connectors() calls the
type-specific msm_dsi_modeset_init(), msm_dp_modeset_init() and
msm_hdmi_modeset_init() functions, so it has to know about each concrete
sub-block type.

Introduce a small struct msm_display interface with a modeset_init()
callback, embedded in struct hdmi, struct msm_dsi and struct msm_dp. Each
sub-block registers its ops and provides a msm_*_get_display() accessor;
the common code then dispatches through display->funcs->modeset_init()
without knowing the concrete type. Further per-sub-block operations will
be folded into this interface in following patches.

No functional change intended.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <[email protected]>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 17 ++++++++--
 drivers/gpu/drm/msm/dp/dp_display.h |  2 ++
 drivers/gpu/drm/msm/dsi/dsi.c       | 18 ++++++++--
 drivers/gpu/drm/msm/dsi/dsi.h       |  2 ++
 drivers/gpu/drm/msm/hdmi/hdmi.c     | 13 +++++++-
 drivers/gpu/drm/msm/hdmi/hdmi.h     |  2 ++
 drivers/gpu/drm/msm/msm_drv.h       | 50 ++++++++++++++++++----------
 drivers/gpu/drm/msm/msm_kms.c       | 66 ++++++++++++++++++-------------------
 8 files changed, 115 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 5ae5eed7e010..79dd556e96c2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -203,6 +203,8 @@ void msm_dp_display_signal_audio_complete(struct msm_dp 
*msm_dp_display)
        complete_all(&dp->audio_comp);
 }
 
+static const struct msm_display_funcs msm_dp_display_funcs;
+
 static int msm_dp_display_bind(struct device *dev, struct device *master,
                           void *data)
 {
@@ -212,6 +214,7 @@ static int msm_dp_display_bind(struct device *dev, struct 
device *master,
        struct drm_device *drm = priv->dev;
 
        dp->msm_dp_display.drm_dev = drm;
+       dp->msm_dp_display.display.funcs = &msm_dp_display_funcs;
        priv->kms->dp[dp->id] = &dp->msm_dp_display;
 
        dp->drm_dev = drm;
@@ -1317,9 +1320,10 @@ void msm_dp_display_debugfs_init(struct msm_dp 
*msm_dp_display, struct dentry *r
                DRM_ERROR("failed to initialize debug, rc = %d\n", rc);
 }
 
-int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
-                       struct drm_encoder *encoder)
+static int msm_dp_modeset_init(struct msm_display *display,
+                              struct drm_device *dev, struct drm_encoder 
*encoder)
 {
+       struct msm_dp *msm_dp_display = container_of(display, struct msm_dp, 
display);
        struct msm_dp_display_private *msm_dp_priv;
        int ret;
 
@@ -1348,6 +1352,15 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, 
struct drm_device *dev,
        return 0;
 }
 
+static const struct msm_display_funcs msm_dp_display_funcs = {
+       .modeset_init = msm_dp_modeset_init,
+};
+
+struct msm_display *msm_dp_get_display(struct msm_dp *msm_dp_display)
+{
+       return msm_dp_display ? &msm_dp_display->display : NULL;
+}
+
 void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
                                 struct drm_atomic_commit *state)
 {
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index 0b65e16c790d..20a71afb1f90 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -12,6 +12,8 @@
 #define DP_MAX_PIXEL_CLK_KHZ   675000
 
 struct msm_dp {
+       struct msm_display display;
+
        struct drm_device *drm_dev;
        struct platform_device *pdev;
        struct drm_connector *connector;
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 3c9f01ed6271..6cd844d08733 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -115,6 +115,8 @@ static struct msm_dsi *dsi_init(struct platform_device 
*pdev)
        return ERR_PTR(ret);
 }
 
+static const struct msm_display_funcs msm_dsi_display_funcs;
+
 static int dsi_bind(struct device *dev, struct device *master, void *data)
 {
        struct msm_drm_private *priv = dev_get_drvdata(master);
@@ -136,6 +138,7 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
                msm_dsi->next_bridge = ext_bridge;
        }
 
+       msm_dsi->display.funcs = &msm_dsi_display_funcs;
        priv->kms->dsi[msm_dsi->id] = msm_dsi;
 
        return 0;
@@ -230,9 +233,11 @@ void __exit msm_dsi_unregister(void)
        platform_driver_unregister(&dsi_driver);
 }
 
-int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
-                        struct drm_encoder *encoder)
+static int msm_dsi_modeset_init(struct msm_display *display,
+                               struct drm_device *dev,
+                               struct drm_encoder *encoder)
 {
+       struct msm_dsi *msm_dsi = container_of(display, struct msm_dsi, 
display);
        int ret;
 
        msm_dsi->dev = dev;
@@ -262,6 +267,15 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct 
drm_device *dev,
        return 0;
 }
 
+static const struct msm_display_funcs msm_dsi_display_funcs = {
+       .modeset_init = msm_dsi_modeset_init,
+};
+
+struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi)
+{
+       return msm_dsi ? &msm_dsi->display : NULL;
+}
+
 void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi 
*msm_dsi)
 {
        msm_dsi_host_snapshot(disp_state, msm_dsi->host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 93c028a122f3..1d1bda0682db 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -32,6 +32,8 @@ enum msm_dsi_phy_usecase {
 #define DSI_BUS_CLK_MAX                4
 
 struct msm_dsi {
+       struct msm_display display;
+
        struct drm_device *dev;
        struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 474006084633..03367c6ba428 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -159,9 +159,10 @@ static int msm_hdmi_init(struct hdmi *hdmi)
  * should be handled in msm_hdmi_init() so that failure happens from
  * hdmi sub-device's probe.
  */
-int msm_hdmi_modeset_init(struct hdmi *hdmi,
+static int msm_hdmi_modeset_init(struct msm_display *display,
                struct drm_device *dev, struct drm_encoder *encoder)
 {
+       struct hdmi *hdmi = container_of(display, struct hdmi, display);
        int ret;
 
        hdmi->dev = dev;
@@ -210,6 +211,15 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
        return ret;
 }
 
+static const struct msm_display_funcs msm_hdmi_display_funcs = {
+       .modeset_init = msm_hdmi_modeset_init,
+};
+
+struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi)
+{
+       return hdmi ? &hdmi->display : NULL;
+}
+
 /*
  * The hdmi device:
  */
@@ -243,6 +253,7 @@ static int msm_hdmi_bind(struct device *dev, struct device 
*master, void *data)
        err = msm_hdmi_init(hdmi);
        if (err)
                return err;
+       hdmi->display.funcs = &msm_hdmi_display_funcs;
        priv->kms->hdmi = hdmi;
 
        return 0;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 49433f7727c3..f24444610fe1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -31,6 +31,8 @@ struct hdmi_audio {
 struct hdmi_hdcp_ctrl;
 
 struct hdmi {
+       struct msm_display display;
+
        struct drm_device *dev;
        struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 0ec0622d9217..dbd955091ce7 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -274,17 +274,39 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper 
*helper,
        .fbdev_probe = NULL
 #endif
 
+struct msm_display;
+
+/**
+ * struct msm_display_funcs - ops provided by a display sub-block (DSI/DP/HDMI)
+ * @modeset_init: create the bridge and connector for the sub-block, attaching
+ *                to @encoder.
+ */
+struct msm_display_funcs {
+       int (*modeset_init)(struct msm_display *display, struct drm_device *dev,
+                           struct drm_encoder *encoder);
+};
+
+/**
+ * struct msm_display - common interface to a display sub-block
+ * @funcs: sub-block provided ops
+ *
+ * Embedded in each sub-block (&struct hdmi, &struct msm_dsi, &struct msm_dp)
+ * so that common KMS code can set up their connectors without knowing the
+ * concrete type.
+ */
+struct msm_display {
+       const struct msm_display_funcs *funcs;
+};
+
 struct hdmi;
 #ifdef CONFIG_DRM_MSM_HDMI
-int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
-               struct drm_encoder *encoder);
+struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi);
 void __init msm_hdmi_register(void);
 void __exit msm_hdmi_unregister(void);
 #else
-static inline int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device 
*dev,
-               struct drm_encoder *encoder)
+static inline struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi)
 {
-       return -EINVAL;
+       return NULL;
 }
 static inline void __init msm_hdmi_register(void) {}
 static inline void __exit msm_hdmi_unregister(void) {}
@@ -296,8 +318,7 @@ int dsi_dev_attach(struct platform_device *pdev);
 void dsi_dev_detach(struct platform_device *pdev);
 void __init msm_dsi_register(void);
 void __exit msm_dsi_unregister(void);
-int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
-                        struct drm_encoder *encoder);
+struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi);
 void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi 
*msm_dsi);
 bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
 bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
@@ -312,11 +333,9 @@ static inline void __init msm_dsi_register(void)
 static inline void __exit msm_dsi_unregister(void)
 {
 }
-static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
-                                      struct drm_device *dev,
-                                      struct drm_encoder *encoder)
+static inline struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi)
 {
-       return -EINVAL;
+       return NULL;
 }
 static inline void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct 
msm_dsi *msm_dsi)
 {
@@ -353,8 +372,7 @@ struct msm_dp;
 #ifdef CONFIG_DRM_MSM_DP
 int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
-int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
-                        struct drm_encoder *encoder);
+struct msm_display *msm_dp_get_display(struct msm_dp *dp_display);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp 
*dp_display);
 bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
                               const struct drm_display_mode *mode);
@@ -368,11 +386,9 @@ static inline int __init msm_dp_register(void)
 static inline void __exit msm_dp_unregister(void)
 {
 }
-static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
-                                      struct drm_device *dev,
-                                      struct drm_encoder *encoder)
+static inline struct msm_display *msm_dp_get_display(struct msm_dp *dp_display)
 {
-       return -EINVAL;
+       return NULL;
 }
 
 static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct 
msm_dp *dp_display)
diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
index 87530145e82b..3f855f9b3d06 100644
--- a/drivers/gpu/drm/msm/msm_kms.c
+++ b/drivers/gpu/drm/msm/msm_kms.c
@@ -260,9 +260,24 @@ void msm_drm_kms_uninit(struct device *dev)
                kms->funcs->destroy(kms);
 }
 
+static int msm_display_modeset_init(struct msm_display *display,
+                                   struct drm_device *ddev,
+                                   struct drm_encoder *encoder)
+{
+       if (!display)
+               return 0;
+
+       return display->funcs->modeset_init(display, ddev, encoder);
+}
+
 /*
- * Set up the bridges and connectors for the display sub-blocks, using the
- * encoders the backend created in ->kms_init().
+ * Set up the bridges and connectors for the display sub-blocks, dispatching
+ * through the common display interface using the encoders the backend created
+ * in ->kms_init().
+ *
+ * The slave link of a bonded DSI pair shares its master's encoder and creates
+ * no connector of its own; its ->modeset_init() handles that internally, so it
+ * needs no special-casing here.
  */
 static int msm_kms_init_connectors(struct drm_device *ddev)
 {
@@ -270,45 +285,30 @@ static int msm_kms_init_connectors(struct drm_device 
*ddev)
        struct msm_kms *kms = priv->kms;
        int i, ret;
 
-       /*
-        * The slave link of a bonded DSI pair shares its master's encoder and
-        * creates no connector of its own; msm_dsi_modeset_init() handles that
-        * internally, so it needs no special-casing here.
-        */
        for (i = 0; i < ARRAY_SIZE(kms->dsi); i++) {
-               if (!kms->dsi[i])
-                       continue;
-
-               ret = msm_dsi_modeset_init(kms->dsi[i], ddev, 
kms->dsi_encoder[i]);
-               if (ret) {
-                       DRM_DEV_ERROR(ddev->dev,
-                                     "modeset_init failed for dsi[%d]: %d\n", 
i, ret);
-                       return ret;
-               }
+               ret = msm_display_modeset_init(msm_dsi_get_display(kms->dsi[i]),
+                                              ddev, kms->dsi_encoder[i]);
+               if (ret)
+                       goto fail;
        }
 
        for (i = 0; i < ARRAY_SIZE(kms->dp); i++) {
-               if (!kms->dp[i])
-                       continue;
-
-               ret = msm_dp_modeset_init(kms->dp[i], ddev, kms->dp_encoder[i]);
-               if (ret) {
-                       DRM_DEV_ERROR(ddev->dev,
-                                     "modeset_init failed for dp[%d]: %d\n", 
i, ret);
-                       return ret;
-               }
+               ret = msm_display_modeset_init(msm_dp_get_display(kms->dp[i]),
+                                              ddev, kms->dp_encoder[i]);
+               if (ret)
+                       goto fail;
        }
 
-       if (kms->hdmi) {
-               ret = msm_hdmi_modeset_init(kms->hdmi, ddev, kms->hdmi_encoder);
-               if (ret) {
-                       DRM_DEV_ERROR(ddev->dev,
-                                     "modeset_init failed for HDMI: %d\n", 
ret);
-                       return ret;
-               }
-       }
+       ret = msm_display_modeset_init(msm_hdmi_get_display(kms->hdmi),
+                                      ddev, kms->hdmi_encoder);
+       if (ret)
+               goto fail;
 
        return 0;
+
+fail:
+       DRM_DEV_ERROR(ddev->dev, "modeset_init failed: %d\n", ret);
+       return ret;
 }
 
 int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)

-- 
2.47.3

Reply via email to