drm/hisilicon: Code refactoring for hibmc_drv_de
authorTian Tao <tiantao6@hisilicon.com>
Wed, 12 Aug 2020 07:42:59 +0000 (15:42 +0800)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 12 Aug 2020 08:27:18 +0000 (10:27 +0200)
The memory used to be allocated with devres helpers and released
automatically. In rare circumstances, the memory's release could
have happened before the DRM device got released, which would have
caused memory corruption of some kind. Now we're embedding the data
structures in struct hibmc_drm_private. The whole release problem
has been resolved, because struct hibmc_drm_private is allocated
with drmm_kzalloc and always released with the DRM device.

Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/1597218179-3938-3-git-send-email-tiantao6@hisilicon.com
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h

index 66132eb232ed9b1b9a9722a2d2e7b8232ba3eb82..d9062a3f5b82da52861ac9483646bb1a15334c40 100644 (file)
@@ -157,37 +157,6 @@ static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = {
        .atomic_update = hibmc_plane_atomic_update,
 };
 
-static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
-{
-       struct drm_device *dev = priv->dev;
-       struct drm_plane *plane;
-       int ret = 0;
-
-       plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL);
-       if (!plane) {
-               DRM_ERROR("failed to alloc memory when init plane\n");
-               return ERR_PTR(-ENOMEM);
-       }
-       /*
-        * plane init
-        * TODO: Now only support primary plane, overlay planes
-        * need to do.
-        */
-       ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
-                                      channel_formats1,
-                                      ARRAY_SIZE(channel_formats1),
-                                      NULL,
-                                      DRM_PLANE_TYPE_PRIMARY,
-                                      NULL);
-       if (ret) {
-               DRM_ERROR("failed to init plane: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
-       return plane;
-}
-
 static void hibmc_crtc_dpms(struct drm_crtc *crtc, int dpms)
 {
        struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -534,22 +503,24 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = {
 int hibmc_de_init(struct hibmc_drm_private *priv)
 {
        struct drm_device *dev = priv->dev;
-       struct drm_crtc *crtc;
-       struct drm_plane *plane;
+       struct drm_crtc *crtc = &priv->crtc;
+       struct drm_plane *plane = &priv->primary_plane;
        int ret;
 
-       plane = hibmc_plane_init(priv);
-       if (IS_ERR(plane)) {
-               DRM_ERROR("failed to create plane: %ld\n", PTR_ERR(plane));
-               return PTR_ERR(plane);
-       }
+       ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
+                                      channel_formats1,
+                                      ARRAY_SIZE(channel_formats1),
+                                      NULL,
+                                      DRM_PLANE_TYPE_PRIMARY,
+                                      NULL);
 
-       crtc = devm_kzalloc(dev->dev, sizeof(*crtc), GFP_KERNEL);
-       if (!crtc) {
-               DRM_ERROR("failed to alloc memory when init crtc\n");
-               return -ENOMEM;
+       if (ret) {
+               DRM_ERROR("failed to init plane: %d\n", ret);
+               return ret;
        }
 
+       drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
+
        ret = drm_crtc_init_with_planes(dev, crtc, plane,
                                        NULL, &hibmc_crtc_funcs, NULL);
        if (ret) {
index a6837637af2a4318b1193c3024df1122e521af42..197485e2fe0b23eccbb3b72ebf9eb3397fa84521 100644 (file)
@@ -28,6 +28,8 @@ struct hibmc_drm_private {
 
        /* drm */
        struct drm_device  *dev;
+       struct drm_plane primary_plane;
+       struct drm_crtc crtc;
        struct drm_encoder encoder;
        struct drm_connector connector;
        bool mode_config_initialized;