[PATCH RFC] drm/bridge: panel: Add device_link between panel and master drm device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently the master drm driver is not protected against the attached
panel driver from becoming unavailable. Adding a device_link with
DL_FLAG_AUTOREMOVE flag unbinds the master drm device (the consumer)
when the panel device (the supplier) becomes unavailable.

Signed-off-by: Jyri Sarha <jsarha@xxxxxx>
Suggested-by: Thierry Reding <thierry.reding@xxxxxxxxx>
cc: eric@xxxxxxxxxx
cc: laurent.pinchart@xxxxxxxxxxxxxxxx
---
It still annoys me that the unbound master drm device does not probe
again if the panel device becomes available again. If there is no
remedy to this, may be we should consider applying the module get/put
patch[1] too.

Hmmm... there was an obvious reasons not to add module gets and puts
to drm_panel_attach/detach(), but is there any such reasons for not to
add and remove the device link there?

The bridge side look more complicated as there is no public
drm_bridge_detach(), and I am not sure if the drm_bridge_remove() should
remove the device link. I guess it should, if the link is there.

[1] https://lists.freedesktop.org/archives/dri-devel/2018-February/166350.html

 drivers/gpu/drm/bridge/panel.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 6d99d4a..d71ddd8 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -22,6 +22,7 @@ struct panel_bridge {
 	struct drm_connector connector;
 	struct drm_panel *panel;
 	u32 connector_type;
+	struct device_link *link;	/* link to master drm dev */
 };
 
 static inline struct panel_bridge *
@@ -57,6 +58,22 @@ static const struct drm_connector_funcs panel_bridge_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
+static int panel_bridge_link_to_master(struct panel_bridge *panel_bridge)
+{
+	struct device *mdev = panel_bridge->bridge.dev->dev;
+	struct device *pdev = panel_bridge->panel->dev;
+	u32 flags = DL_FLAG_AUTOREMOVE;
+
+	panel_bridge->link = device_link_add(mdev, pdev, flags);
+	if (!panel_bridge->link) {
+		dev_err(pdev, "failed to link panel %s to %s\n",
+			dev_name(pdev), dev_name(mdev));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int panel_bridge_attach(struct drm_bridge *bridge)
 {
 	struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
@@ -82,6 +99,9 @@ static int panel_bridge_attach(struct drm_bridge *bridge)
 	drm_mode_connector_attach_encoder(&panel_bridge->connector,
 					  bridge->encoder);
 
+	if (panel_bridge_link_to_master(panel_bridge))
+		return -EINVAL;
+
 	ret = drm_panel_attach(panel_bridge->panel, &panel_bridge->connector);
 	if (ret < 0)
 		return ret;
@@ -94,6 +114,8 @@ static void panel_bridge_detach(struct drm_bridge *bridge)
 	struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
 
 	drm_panel_detach(panel_bridge->panel);
+
+	device_link_del(panel_bridge->link);
 }
 
 static void panel_bridge_pre_enable(struct drm_bridge *bridge)
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux