From 39d5b6a64ace77d0c11c398d272218df5f939abb Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 23 Nov 2023 11:26:15 +0800 Subject: drm/bridge: panel: Check device dependency before managing device link Some panel devices already depend on DRM device, like the panel in arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts, because DRM device is the ancestor of those panel devices. device_link_add() would fail by returning a NULL pointer for those panel devices because of the existing dependency. So, check the dependency by calling device_is_dependent() before adding or deleting device link between panel device and DRM device so that the link is managed only for independent panel devices. Fixes: 887878014534 ("drm/bridge: panel: Fix device link for DRM_BRIDGE_ATTACH_NO_CONNECTOR") Fixes: 199cf07ebd2b ("drm/bridge: panel: Add a device link between drm device and panel device") Reported-by: Linus Walleij Closes: https://lore.kernel.org/lkml/CACRpkdaGzXD6HbiX7mVUNJAJtMEPG00Pp6+nJ1P0JrfJ-ArMvQ@mail.gmail.com/T/ Tested-by: Linus Walleij Signed-off-by: Liu Ying Signed-off-by: Linus Walleij Link: https://patchwork.freedesktop.org/patch/msgid/20231123032615.3760488-1-victor.liu@nxp.com --- drivers/gpu/drm/bridge/panel.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/bridge/panel.c') diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index e48823a4f1ed..5e8980023407 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -23,6 +23,7 @@ struct panel_bridge { struct drm_panel *panel; struct device_link *link; u32 connector_type; + bool is_independent; }; static inline struct panel_bridge * @@ -67,12 +68,17 @@ static int panel_bridge_attach(struct drm_bridge *bridge, struct drm_device *drm_dev = bridge->dev; int ret; - panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, - DL_FLAG_STATELESS); - if (!panel_bridge->link) { - DRM_ERROR("Failed to add device link between %s and %s\n", - dev_name(drm_dev->dev), dev_name(panel->dev)); - return -EINVAL; + panel_bridge->is_independent = !device_is_dependent(drm_dev->dev, + panel->dev); + + if (panel_bridge->is_independent) { + panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, + DL_FLAG_STATELESS); + if (!panel_bridge->link) { + DRM_ERROR("Failed to add device link between %s and %s\n", + dev_name(drm_dev->dev), dev_name(panel->dev)); + return -EINVAL; + } } if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) @@ -80,7 +86,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge, if (!bridge->encoder) { DRM_ERROR("Missing encoder\n"); - device_link_del(panel_bridge->link); + if (panel_bridge->is_independent) + device_link_del(panel_bridge->link); return -ENODEV; } @@ -92,7 +99,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge, panel_bridge->connector_type); if (ret) { DRM_ERROR("Failed to initialize connector\n"); - device_link_del(panel_bridge->link); + if (panel_bridge->is_independent) + device_link_del(panel_bridge->link); return ret; } @@ -115,7 +123,8 @@ static void panel_bridge_detach(struct drm_bridge *bridge) struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); struct drm_connector *connector = &panel_bridge->connector; - device_link_del(panel_bridge->link); + if (panel_bridge->is_independent) + device_link_del(panel_bridge->link); /* * Cleanup the connector if we know it was initialized. -- cgit v1.2.3 From c13f87efa7488fcd5f4d6e89c8f9d5bb072f9e6e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 28 Nov 2023 00:10:20 +0100 Subject: Revert "drm/bridge: panel: Check device dependency before managing device link" This reverts commit 39d5b6a64ace77d0c11c398d272218df5f939abb. This patch was causing build errors by using an unexported function from the device core, which Greg questions the saneness in exporting. Link: https://lore.kernel.org/lkml/CACRpkdaGzXD6HbiX7mVUNJAJtMEPG00Pp6+nJ1P0JrfJ-ArMvQ@mail.gmail.com/T/ Signed-off-by: Linus Walleij Acked-by: Neil Armstrong Link: https://lore.kernel.org/r/20231128-revert-panel-fix-v1-2-69bb05048dae@linaro.org Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20231128-revert-panel-fix-v1-2-69bb05048dae@linaro.org --- drivers/gpu/drm/bridge/panel.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/bridge/panel.c') diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 5e8980023407..e48823a4f1ed 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -23,7 +23,6 @@ struct panel_bridge { struct drm_panel *panel; struct device_link *link; u32 connector_type; - bool is_independent; }; static inline struct panel_bridge * @@ -68,17 +67,12 @@ static int panel_bridge_attach(struct drm_bridge *bridge, struct drm_device *drm_dev = bridge->dev; int ret; - panel_bridge->is_independent = !device_is_dependent(drm_dev->dev, - panel->dev); - - if (panel_bridge->is_independent) { - panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, - DL_FLAG_STATELESS); - if (!panel_bridge->link) { - DRM_ERROR("Failed to add device link between %s and %s\n", - dev_name(drm_dev->dev), dev_name(panel->dev)); - return -EINVAL; - } + panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, + DL_FLAG_STATELESS); + if (!panel_bridge->link) { + DRM_ERROR("Failed to add device link between %s and %s\n", + dev_name(drm_dev->dev), dev_name(panel->dev)); + return -EINVAL; } if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) @@ -86,8 +80,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge, if (!bridge->encoder) { DRM_ERROR("Missing encoder\n"); - if (panel_bridge->is_independent) - device_link_del(panel_bridge->link); + device_link_del(panel_bridge->link); return -ENODEV; } @@ -99,8 +92,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge, panel_bridge->connector_type); if (ret) { DRM_ERROR("Failed to initialize connector\n"); - if (panel_bridge->is_independent) - device_link_del(panel_bridge->link); + device_link_del(panel_bridge->link); return ret; } @@ -123,8 +115,7 @@ static void panel_bridge_detach(struct drm_bridge *bridge) struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); struct drm_connector *connector = &panel_bridge->connector; - if (panel_bridge->is_independent) - device_link_del(panel_bridge->link); + device_link_del(panel_bridge->link); /* * Cleanup the connector if we know it was initialized. -- cgit v1.2.3 From 9b6a59e5db87c2c6b3ca0391176ed4358623d5e4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 28 Nov 2023 00:10:21 +0100 Subject: Revert "drm/bridge: panel: Add a device link between drm device and panel device" This reverts commit 199cf07ebd2b0d41185ac79b895547d45610b681. This patch creates bugs on devices where the DRM device is the ancestor of the panel devices. Attempts to fix this have failed because it leads to using device core functionality which is questionable. Reported-by: Linus Walleij Link: https://lore.kernel.org/lkml/CACRpkdaGzXD6HbiX7mVUNJAJtMEPG00Pp6+nJ1P0JrfJ-ArMvQ@mail.gmail.com/T/ Signed-off-by: Linus Walleij Acked-by: Neil Armstrong Link: https://lore.kernel.org/r/20231128-revert-panel-fix-v1-3-69bb05048dae@linaro.org Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20231128-revert-panel-fix-v1-3-69bb05048dae@linaro.org --- drivers/gpu/drm/bridge/panel.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers/gpu/drm/bridge/panel.c') diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index e48823a4f1ed..7f41525f7a6e 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -4,8 +4,6 @@ * Copyright (C) 2017 Broadcom */ -#include - #include #include #include @@ -21,7 +19,6 @@ struct panel_bridge { struct drm_bridge bridge; struct drm_connector connector; struct drm_panel *panel; - struct device_link *link; u32 connector_type; }; @@ -63,24 +60,13 @@ static int panel_bridge_attach(struct drm_bridge *bridge, { struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); struct drm_connector *connector = &panel_bridge->connector; - struct drm_panel *panel = panel_bridge->panel; - struct drm_device *drm_dev = bridge->dev; int ret; - panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, - DL_FLAG_STATELESS); - if (!panel_bridge->link) { - DRM_ERROR("Failed to add device link between %s and %s\n", - dev_name(drm_dev->dev), dev_name(panel->dev)); - return -EINVAL; - } - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) return 0; if (!bridge->encoder) { DRM_ERROR("Missing encoder\n"); - device_link_del(panel_bridge->link); return -ENODEV; } @@ -92,7 +78,6 @@ static int panel_bridge_attach(struct drm_bridge *bridge, panel_bridge->connector_type); if (ret) { DRM_ERROR("Failed to initialize connector\n"); - device_link_del(panel_bridge->link); return ret; } @@ -115,8 +100,6 @@ static void panel_bridge_detach(struct drm_bridge *bridge) struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); struct drm_connector *connector = &panel_bridge->connector; - device_link_del(panel_bridge->link); - /* * Cleanup the connector if we know it was initialized. * -- cgit v1.2.3