]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Thu, 3 Apr 2025 10:47:39 +0000 (12:47 +0200)
committerChun-Kuang Hu <chunkuang.hu@kernel.org>
Wed, 14 May 2025 23:08:10 +0000 (23:08 +0000)
When calling component_bind_all(), if a component that is included
in the list fails, all of those that have been successfully bound
will be unbound, but this driver has two components lists for two
actual devices, as in, each mmsys instance has its own components
list.

In case mmsys0 (or actually vdosys0) is able to bind all of its
components, but the secondary one fails, all of the components of
the first are kept bound, while the ones of mmsys1/vdosys1 are
correctly cleaned up.

This is not right because, in case of a failure, the components
are re-bound for all of the mmsys/vdosys instances without caring
about the ones that were previously left in a bound state.

Fix that by calling component_unbind_all() on all of the previous
component masters that succeeded binding all subdevices when any
of the other masters errors out.

Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-4-angelogioacchino.delregno@collabora.com/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
drivers/gpu/drm/mediatek/mtk_drm_drv.c

index 593193555c07efeb9a4e925083332c091cbfee8a..7c0c12dde48859f6c63e8f9b1dd861d94623508f 100644 (file)
@@ -488,8 +488,11 @@ static int mtk_drm_kms_init(struct drm_device *drm)
        for (i = 0; i < private->data->mmsys_dev_num; i++) {
                drm->dev_private = private->all_drm_private[i];
                ret = component_bind_all(private->all_drm_private[i]->dev, drm);
-               if (ret)
+               if (ret) {
+                       while (--i >= 0)
+                               component_unbind_all(private->all_drm_private[i]->dev, drm);
                        return ret;
+               }
        }
 
        /*