All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andy Yan" <andyshrk@163.com>
To: "Sebastian Reichel" <sebastian.reichel@collabora.com>
Cc: "Sandy Huang" <hjc@rock-chips.com>,
	"Heiko Stübner" <heiko@sntech.de>,
	"Andy Yan" <andy.yan@rock-chips.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"Andrzej Hajda" <andrzej.hajda@intel.com>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Robert Foss" <rfoss@kernel.org>,
	"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
	"Jonas Karlman" <jonas@kwiboo.se>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>,
	"Luca Ceresoli" <luca.ceresoli@bootlin.com>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Cristian Ciocaltea" <cristian.ciocaltea@collabora.com>,
	"Damon Ding" <damon.ding@rock-chips.com>,
	"Dmitry Baryshkov" <lumag@kernel.org>,
	"Alexey Charkov" <alchark@flipper.net>,
	dri-devel@lists.freedesktop.org,
	linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, kernel@collabora.com,
	linux-arm-kernel@lists.infradead.org,
	Sashiko <sashiko-bot@kernel.org>
Subject: Re:[PATCH v11 02/21] drm/bridge: synopsys: dw-dp: Fix incorrect resource lifetimes in bind callback
Date: Sun, 16 Aug 2026 20:41:30 +0800 (CST)	[thread overview]
Message-ID: <78ac4580.18bf.1a00a976aac.Coremail.andyshrk@163.com> (raw)
In-Reply-To: <20260806-synopsys-dw-dp-improvements-v11-2-0d508505f383@collabora.com>


Hello Sebastian,

At 2026-08-07 01:02:08, "Sebastian Reichel" <sebastian.reichel@collabora.com> wrote:
>Currently the Synopsys DesignWare DP controller driver's bind function
>requests lots of resources using device managed functions. These are
>free'd on driver removal instead of at unbind time. Fix this discrepancy
>by introducing a new probe helper function and moving over the whole
>bind function. This results in a fully functional DRM bridge once probe
>succeeded. The only thing still happening when the component is bound
>is the bridge attachment, which requires the encoder.
>
>The interrupt is kept disabled while the bridge is detached to ensure no
>spurious interrupts can arrive as the interrupt handler triggers a
>worker, which accesses the DRM device.
>
>Fixes: 86eecc3a9c2e ("drm/bridge: synopsys: Add DW DPTX Controller support library")
>Reported-by: Sashiko <sashiko-bot@kernel.org>
>Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

   Acked-by: Andy Yan <andy.yan@rock-chips.com>

>---
> drivers/gpu/drm/bridge/synopsys/dw-dp.c   | 73 ++++++++++++++++---------------
> drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 53 ++++++++++++----------
> include/drm/bridge/dw_dp.h                |  5 ++-
> 3 files changed, 72 insertions(+), 59 deletions(-)
>
>diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>index 60feb3d1e14b..d7945f7fe9f0 100644
>--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>@@ -1827,16 +1827,22 @@ static int dw_dp_bridge_attach(struct drm_bridge *bridge,
> 	dp->aux.transfer = dw_dp_aux_transfer;
> 
> 	ret = drm_dp_aux_register(&dp->aux);
>-	if (ret)
>+	if (ret) {
> 		dev_err(dev, "Aux register failed: %d\n", ret);
>+		return ret;
>+	}
> 
>-	return ret;
>+	enable_irq(dp->irq);
>+
>+	return 0;
> }
> 
> static void dw_dp_bridge_detach(struct drm_bridge *bridge)
> {
> 	struct dw_dp *dp = bridge_to_dp(bridge);
> 
>+	disable_irq(dp->irq);
>+	cancel_work_sync(&dp->hpd_work);
> 	drm_dp_aux_unregister(&dp->aux);
> }
> 
>@@ -1982,6 +1988,18 @@ static const struct regmap_config dw_dp_regmap_config = {
> 	.rd_table = &dw_dp_readable_table,
> };
> 
>+int dw_dp_bind(struct dw_dp *dp, struct drm_encoder *encoder)
>+{
>+	return drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>+}
>+EXPORT_SYMBOL_GPL(dw_dp_bind);
>+
>+void dw_dp_unbind(struct dw_dp *dp)
>+{
>+	/* nothing to do as bridge is detached automatically */
>+}
>+EXPORT_SYMBOL_GPL(dw_dp_unbind);
>+
> static void dw_dp_phy_exit(void *data)
> {
> 	struct dw_dp *dp = data;
>@@ -1989,13 +2007,12 @@ static void dw_dp_phy_exit(void *data)
> 	phy_exit(dp->phy);
> }
> 
>-struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
>-			 const struct dw_dp_plat_data *plat_data)
>+struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_data *plat_data)
> {
>-	struct platform_device *pdev = to_platform_device(dev);
>-	struct dw_dp *dp;
>+	struct device *dev = &pdev->dev;
> 	struct drm_bridge *bridge;
> 	void __iomem *res;
>+	struct dw_dp *dp;
> 	int ret;
> 
> 	dp = devm_drm_bridge_alloc(dev, struct dw_dp, bridge, &dw_dp_bridge_funcs);
>@@ -2004,9 +2021,8 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 
> 	dp->dev = dev;
> 	dp->pixel_mode = plat_data->pixel_mode;
>-
> 	dp->plat_data.max_link_rate = plat_data->max_link_rate;
>-	bridge = &dp->bridge;
>+
> 	mutex_init(&dp->irq_lock);
> 	INIT_WORK(&dp->hpd_work, dw_dp_hpd_work);
> 	init_completion(&dp->complete);
>@@ -2063,18 +2079,14 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 		return ERR_CAST(dp->rstc);
> 	}
> 
>-	bridge->of_node = dev->of_node;
>-	bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>-	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
>-	bridge->ycbcr_420_allowed = true;
>-
>-	ret = devm_drm_bridge_add(dev, bridge);
>-	if (ret)
>-		return ERR_PTR(ret);
>+	dp->irq = platform_get_irq(pdev, 0);
>+	if (dp->irq < 0)
>+		return ERR_PTR(dp->irq);
> 
>-	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>+	ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq,
>+					IRQF_ONESHOT | IRQF_NO_AUTOEN, dev_name(dev), dp);
> 	if (ret) {
>-		dev_err_probe(dev, ret, "Failed to attach bridge\n");
>+		dev_err_probe(dev, ret, "failed to request irq\n");
> 		return ERR_PTR(ret);
> 	}
> 
>@@ -2090,28 +2102,19 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 	if (ret)
> 		return ERR_PTR(ret);
> 
>-	dp->irq = platform_get_irq(pdev, 0);
>-	if (dp->irq < 0) {
>-		ret = dp->irq;
>-		return ERR_PTR(ret);
>-	}
>+	bridge = &dp->bridge;
>+	bridge->of_node = dev->of_node;
>+	bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
>+	bridge->ycbcr_420_allowed = true;
> 
>-	ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq,
>-					IRQF_ONESHOT, dev_name(dev), dp);
>-	if (ret) {
>-		dev_err_probe(dev, ret, "failed to request irq\n");
>+	ret = devm_drm_bridge_add(dev, bridge);
>+	if (ret)
> 		return ERR_PTR(ret);
>-	}
> 
> 	return dp;
> }
>-EXPORT_SYMBOL_GPL(dw_dp_bind);
>-
>-void dw_dp_unbind(struct dw_dp *dp)
>-{
>-	/* nothing to do */
>-}
>-EXPORT_SYMBOL_GPL(dw_dp_unbind);
>+EXPORT_SYMBOL_GPL(dw_dp_probe);
> 
> MODULE_AUTHOR("Andy Yan <andyshrk@163.com>");
> MODULE_DESCRIPTION("DW DP Core Library");
>diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>index b23efb153c9e..38e8fe75718e 100644
>--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>@@ -26,7 +26,7 @@
> struct rockchip_dw_dp {
> 	struct dw_dp *base;
> 	struct device *dev;
>-	struct rockchip_encoder encoder;
>+	struct rockchip_encoder *encoder;
> };
> 
> static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
>@@ -73,37 +73,28 @@ static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = {
> 
> static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *data)
> {
>-	struct platform_device *pdev = to_platform_device(dev);
>-	const struct dw_dp_plat_data *plat_data;
>+	struct rockchip_dw_dp *dp = dev_get_drvdata(dev);
> 	struct drm_device *drm_dev = data;
>-	struct rockchip_dw_dp *dp;
> 	struct drm_encoder *encoder;
> 	struct drm_connector *connector;
> 	int ret;
> 
>-	dp = drmm_kzalloc(drm_dev, sizeof(*dp), GFP_KERNEL);
>-	if (!dp)
>+	dp->encoder = drmm_kzalloc(drm_dev, sizeof(*dp->encoder), GFP_KERNEL);
>+	if (!dp->encoder)
> 		return -ENOMEM;
> 
>-	dp->dev = dev;
>-	platform_set_drvdata(pdev, dp);
>-
>-	plat_data = of_device_get_match_data(dev);
>-	if (!plat_data)
>-		return -ENODEV;
>-
>-	encoder = &dp->encoder.encoder;
>+	encoder = &dp->encoder->encoder;
> 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, dev->of_node);
>-	rockchip_drm_encoder_set_crtc_endpoint_id(&dp->encoder, dev->of_node, 0, 0);
>+	rockchip_drm_encoder_set_crtc_endpoint_id(dp->encoder, dev->of_node, 0, 0);
> 
> 	ret = drmm_encoder_init(drm_dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL);
> 	if (ret)
> 		return ret;
> 	drm_encoder_helper_add(encoder, &dw_dp_encoder_helper_funcs);
> 
>-	dp->base = dw_dp_bind(dev, encoder, plat_data);
>-	if (IS_ERR(dp->base))
>-		return PTR_ERR(dp->base);
>+	ret = dw_dp_bind(dp->base, encoder);
>+	if (ret)
>+		return dev_err_probe(dev, ret, "failed to bind DW-DP bridge\n");
> 
> 	connector = drm_bridge_connector_init(drm_dev, encoder);
> 	if (IS_ERR(connector)) {
>@@ -128,12 +119,30 @@ static const struct component_ops dw_dp_rockchip_component_ops = {
> 	.unbind = dw_dp_rockchip_unbind,
> };
> 
>-static int dw_dp_probe(struct platform_device *pdev)
>+static int dw_dp_rockchip_probe(struct platform_device *pdev)
> {
>+	const struct dw_dp_plat_data *plat_data;
>+	struct device *dev = &pdev->dev;
>+	struct rockchip_dw_dp *dp;
>+
>+	plat_data = of_device_get_match_data(dev);
>+	if (!plat_data)
>+		return -ENODEV;
>+
>+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
>+	if (!dp)
>+		return -ENOMEM;
>+	platform_set_drvdata(pdev, dp);
>+	dp->dev = dev;
>+
>+	dp->base = dw_dp_probe(pdev, plat_data);
>+	if (IS_ERR(dp->base))
>+		return PTR_ERR(dp->base);
>+
> 	return component_add(&pdev->dev, &dw_dp_rockchip_component_ops);
> }
> 
>-static void dw_dp_remove(struct platform_device *pdev)
>+static void dw_dp_rockchip_remove(struct platform_device *pdev)
> {
> 	component_del(&pdev->dev, &dw_dp_rockchip_component_ops);
> }
>@@ -161,8 +170,8 @@ static const struct of_device_id dw_dp_of_match[] = {
> MODULE_DEVICE_TABLE(of, dw_dp_of_match);
> 
> struct platform_driver dw_dp_driver = {
>-	.probe	= dw_dp_probe,
>-	.remove = dw_dp_remove,
>+	.probe	= dw_dp_rockchip_probe,
>+	.remove = dw_dp_rockchip_remove,
> 	.driver = {
> 		.name = "dw-dp",
> 		.of_match_table = dw_dp_of_match,
>diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
>index 22105c3e8e4d..a82412a9e769 100644
>--- a/include/drm/bridge/dw_dp.h
>+++ b/include/drm/bridge/dw_dp.h
>@@ -22,7 +22,8 @@ struct dw_dp_plat_data {
> 	u8 pixel_mode;
> };
> 
>-struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
>-			 const struct dw_dp_plat_data *plat_data);
>+int dw_dp_bind(struct dw_dp *dp, struct drm_encoder *encoder);
> void dw_dp_unbind(struct dw_dp *dp);
>+
>+struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_data *plat_data);
> #endif /* __DW_DP__ */
>
>-- 
>2.53.0
>

WARNING: multiple messages have this Message-ID (diff)
From: "Andy Yan" <andyshrk@163.com>
To: "Sebastian Reichel" <sebastian.reichel@collabora.com>
Cc: "Heiko Stübner" <heiko@sntech.de>,
	Sashiko <sashiko-bot@kernel.org>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
	"Andrzej Hajda" <andrzej.hajda@intel.com>,
	kernel@collabora.com, "David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Rob Herring" <robh@kernel.org>, "Robert Foss" <rfoss@kernel.org>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	linux-rockchip@lists.infradead.org,
	"Luca Ceresoli" <luca.ceresoli@bootlin.com>,
	devicetree@vger.kernel.org, "Conor Dooley" <conor+dt@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"Jonas Karlman" <jonas@kwiboo.se>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Alexey Charkov" <alchark@flipper.net>,
	"Damon Ding" <damon.ding@rock-chips.com>,
	linux-arm-kernel@lists.infradead.org,
	"Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Dmitry Baryshkov" <lumag@kernel.org>,
	"Sandy Huang" <hjc@rock-chips.com>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Andy Yan" <andy.yan@rock-chips.com>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>
Subject: Re:[PATCH v11 02/21] drm/bridge: synopsys: dw-dp: Fix incorrect resource lifetimes in bind callback
Date: Sun, 16 Aug 2026 20:41:30 +0800 (CST)	[thread overview]
Message-ID: <78ac4580.18bf.1a00a976aac.Coremail.andyshrk@163.com> (raw)
In-Reply-To: <20260806-synopsys-dw-dp-improvements-v11-2-0d508505f383@collabora.com>


Hello Sebastian,

At 2026-08-07 01:02:08, "Sebastian Reichel" <sebastian.reichel@collabora.com> wrote:
>Currently the Synopsys DesignWare DP controller driver's bind function
>requests lots of resources using device managed functions. These are
>free'd on driver removal instead of at unbind time. Fix this discrepancy
>by introducing a new probe helper function and moving over the whole
>bind function. This results in a fully functional DRM bridge once probe
>succeeded. The only thing still happening when the component is bound
>is the bridge attachment, which requires the encoder.
>
>The interrupt is kept disabled while the bridge is detached to ensure no
>spurious interrupts can arrive as the interrupt handler triggers a
>worker, which accesses the DRM device.
>
>Fixes: 86eecc3a9c2e ("drm/bridge: synopsys: Add DW DPTX Controller support library")
>Reported-by: Sashiko <sashiko-bot@kernel.org>
>Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

   Acked-by: Andy Yan <andy.yan@rock-chips.com>

>---
> drivers/gpu/drm/bridge/synopsys/dw-dp.c   | 73 ++++++++++++++++---------------
> drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 53 ++++++++++++----------
> include/drm/bridge/dw_dp.h                |  5 ++-
> 3 files changed, 72 insertions(+), 59 deletions(-)
>
>diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>index 60feb3d1e14b..d7945f7fe9f0 100644
>--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
>@@ -1827,16 +1827,22 @@ static int dw_dp_bridge_attach(struct drm_bridge *bridge,
> 	dp->aux.transfer = dw_dp_aux_transfer;
> 
> 	ret = drm_dp_aux_register(&dp->aux);
>-	if (ret)
>+	if (ret) {
> 		dev_err(dev, "Aux register failed: %d\n", ret);
>+		return ret;
>+	}
> 
>-	return ret;
>+	enable_irq(dp->irq);
>+
>+	return 0;
> }
> 
> static void dw_dp_bridge_detach(struct drm_bridge *bridge)
> {
> 	struct dw_dp *dp = bridge_to_dp(bridge);
> 
>+	disable_irq(dp->irq);
>+	cancel_work_sync(&dp->hpd_work);
> 	drm_dp_aux_unregister(&dp->aux);
> }
> 
>@@ -1982,6 +1988,18 @@ static const struct regmap_config dw_dp_regmap_config = {
> 	.rd_table = &dw_dp_readable_table,
> };
> 
>+int dw_dp_bind(struct dw_dp *dp, struct drm_encoder *encoder)
>+{
>+	return drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>+}
>+EXPORT_SYMBOL_GPL(dw_dp_bind);
>+
>+void dw_dp_unbind(struct dw_dp *dp)
>+{
>+	/* nothing to do as bridge is detached automatically */
>+}
>+EXPORT_SYMBOL_GPL(dw_dp_unbind);
>+
> static void dw_dp_phy_exit(void *data)
> {
> 	struct dw_dp *dp = data;
>@@ -1989,13 +2007,12 @@ static void dw_dp_phy_exit(void *data)
> 	phy_exit(dp->phy);
> }
> 
>-struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
>-			 const struct dw_dp_plat_data *plat_data)
>+struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_data *plat_data)
> {
>-	struct platform_device *pdev = to_platform_device(dev);
>-	struct dw_dp *dp;
>+	struct device *dev = &pdev->dev;
> 	struct drm_bridge *bridge;
> 	void __iomem *res;
>+	struct dw_dp *dp;
> 	int ret;
> 
> 	dp = devm_drm_bridge_alloc(dev, struct dw_dp, bridge, &dw_dp_bridge_funcs);
>@@ -2004,9 +2021,8 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 
> 	dp->dev = dev;
> 	dp->pixel_mode = plat_data->pixel_mode;
>-
> 	dp->plat_data.max_link_rate = plat_data->max_link_rate;
>-	bridge = &dp->bridge;
>+
> 	mutex_init(&dp->irq_lock);
> 	INIT_WORK(&dp->hpd_work, dw_dp_hpd_work);
> 	init_completion(&dp->complete);
>@@ -2063,18 +2079,14 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 		return ERR_CAST(dp->rstc);
> 	}
> 
>-	bridge->of_node = dev->of_node;
>-	bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>-	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
>-	bridge->ycbcr_420_allowed = true;
>-
>-	ret = devm_drm_bridge_add(dev, bridge);
>-	if (ret)
>-		return ERR_PTR(ret);
>+	dp->irq = platform_get_irq(pdev, 0);
>+	if (dp->irq < 0)
>+		return ERR_PTR(dp->irq);
> 
>-	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>+	ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq,
>+					IRQF_ONESHOT | IRQF_NO_AUTOEN, dev_name(dev), dp);
> 	if (ret) {
>-		dev_err_probe(dev, ret, "Failed to attach bridge\n");
>+		dev_err_probe(dev, ret, "failed to request irq\n");
> 		return ERR_PTR(ret);
> 	}
> 
>@@ -2090,28 +2102,19 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> 	if (ret)
> 		return ERR_PTR(ret);
> 
>-	dp->irq = platform_get_irq(pdev, 0);
>-	if (dp->irq < 0) {
>-		ret = dp->irq;
>-		return ERR_PTR(ret);
>-	}
>+	bridge = &dp->bridge;
>+	bridge->of_node = dev->of_node;
>+	bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
>+	bridge->ycbcr_420_allowed = true;
> 
>-	ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq,
>-					IRQF_ONESHOT, dev_name(dev), dp);
>-	if (ret) {
>-		dev_err_probe(dev, ret, "failed to request irq\n");
>+	ret = devm_drm_bridge_add(dev, bridge);
>+	if (ret)
> 		return ERR_PTR(ret);
>-	}
> 
> 	return dp;
> }
>-EXPORT_SYMBOL_GPL(dw_dp_bind);
>-
>-void dw_dp_unbind(struct dw_dp *dp)
>-{
>-	/* nothing to do */
>-}
>-EXPORT_SYMBOL_GPL(dw_dp_unbind);
>+EXPORT_SYMBOL_GPL(dw_dp_probe);
> 
> MODULE_AUTHOR("Andy Yan <andyshrk@163.com>");
> MODULE_DESCRIPTION("DW DP Core Library");
>diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>index b23efb153c9e..38e8fe75718e 100644
>--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
>@@ -26,7 +26,7 @@
> struct rockchip_dw_dp {
> 	struct dw_dp *base;
> 	struct device *dev;
>-	struct rockchip_encoder encoder;
>+	struct rockchip_encoder *encoder;
> };
> 
> static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
>@@ -73,37 +73,28 @@ static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = {
> 
> static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *data)
> {
>-	struct platform_device *pdev = to_platform_device(dev);
>-	const struct dw_dp_plat_data *plat_data;
>+	struct rockchip_dw_dp *dp = dev_get_drvdata(dev);
> 	struct drm_device *drm_dev = data;
>-	struct rockchip_dw_dp *dp;
> 	struct drm_encoder *encoder;
> 	struct drm_connector *connector;
> 	int ret;
> 
>-	dp = drmm_kzalloc(drm_dev, sizeof(*dp), GFP_KERNEL);
>-	if (!dp)
>+	dp->encoder = drmm_kzalloc(drm_dev, sizeof(*dp->encoder), GFP_KERNEL);
>+	if (!dp->encoder)
> 		return -ENOMEM;
> 
>-	dp->dev = dev;
>-	platform_set_drvdata(pdev, dp);
>-
>-	plat_data = of_device_get_match_data(dev);
>-	if (!plat_data)
>-		return -ENODEV;
>-
>-	encoder = &dp->encoder.encoder;
>+	encoder = &dp->encoder->encoder;
> 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, dev->of_node);
>-	rockchip_drm_encoder_set_crtc_endpoint_id(&dp->encoder, dev->of_node, 0, 0);
>+	rockchip_drm_encoder_set_crtc_endpoint_id(dp->encoder, dev->of_node, 0, 0);
> 
> 	ret = drmm_encoder_init(drm_dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL);
> 	if (ret)
> 		return ret;
> 	drm_encoder_helper_add(encoder, &dw_dp_encoder_helper_funcs);
> 
>-	dp->base = dw_dp_bind(dev, encoder, plat_data);
>-	if (IS_ERR(dp->base))
>-		return PTR_ERR(dp->base);
>+	ret = dw_dp_bind(dp->base, encoder);
>+	if (ret)
>+		return dev_err_probe(dev, ret, "failed to bind DW-DP bridge\n");
> 
> 	connector = drm_bridge_connector_init(drm_dev, encoder);
> 	if (IS_ERR(connector)) {
>@@ -128,12 +119,30 @@ static const struct component_ops dw_dp_rockchip_component_ops = {
> 	.unbind = dw_dp_rockchip_unbind,
> };
> 
>-static int dw_dp_probe(struct platform_device *pdev)
>+static int dw_dp_rockchip_probe(struct platform_device *pdev)
> {
>+	const struct dw_dp_plat_data *plat_data;
>+	struct device *dev = &pdev->dev;
>+	struct rockchip_dw_dp *dp;
>+
>+	plat_data = of_device_get_match_data(dev);
>+	if (!plat_data)
>+		return -ENODEV;
>+
>+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
>+	if (!dp)
>+		return -ENOMEM;
>+	platform_set_drvdata(pdev, dp);
>+	dp->dev = dev;
>+
>+	dp->base = dw_dp_probe(pdev, plat_data);
>+	if (IS_ERR(dp->base))
>+		return PTR_ERR(dp->base);
>+
> 	return component_add(&pdev->dev, &dw_dp_rockchip_component_ops);
> }
> 
>-static void dw_dp_remove(struct platform_device *pdev)
>+static void dw_dp_rockchip_remove(struct platform_device *pdev)
> {
> 	component_del(&pdev->dev, &dw_dp_rockchip_component_ops);
> }
>@@ -161,8 +170,8 @@ static const struct of_device_id dw_dp_of_match[] = {
> MODULE_DEVICE_TABLE(of, dw_dp_of_match);
> 
> struct platform_driver dw_dp_driver = {
>-	.probe	= dw_dp_probe,
>-	.remove = dw_dp_remove,
>+	.probe	= dw_dp_rockchip_probe,
>+	.remove = dw_dp_rockchip_remove,
> 	.driver = {
> 		.name = "dw-dp",
> 		.of_match_table = dw_dp_of_match,
>diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
>index 22105c3e8e4d..a82412a9e769 100644
>--- a/include/drm/bridge/dw_dp.h
>+++ b/include/drm/bridge/dw_dp.h
>@@ -22,7 +22,8 @@ struct dw_dp_plat_data {
> 	u8 pixel_mode;
> };
> 
>-struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
>-			 const struct dw_dp_plat_data *plat_data);
>+int dw_dp_bind(struct dw_dp *dp, struct drm_encoder *encoder);
> void dw_dp_unbind(struct dw_dp *dp);
>+
>+struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_data *plat_data);
> #endif /* __DW_DP__ */
>
>-- 
>2.53.0
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

  parent reply	other threads:[~2026-08-16 12:43 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06 17:02 [PATCH v11 00/21] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
2026-08-06 17:02 ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 01/21] drm/bridge: synopsys: dw-dp: Register DP AUX on bridge attach Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:37   ` sashiko-bot
2026-08-16 12:37   ` Andy Yan
2026-08-16 12:37     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 02/21] drm/bridge: synopsys: dw-dp: Fix incorrect resource lifetimes in bind callback Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:36   ` sashiko-bot
2026-08-16 12:41   ` Andy Yan [this message]
2026-08-16 12:41     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 03/21] drm/bridge: synopsys: dw-dp: Fix error handling for DP link enablement Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:29   ` sashiko-bot
2026-08-16 12:44   ` Andy Yan
2026-08-16 12:44     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 04/21] drm/bridge: synopsys: dw-dp: Document missing reset line deassert Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:33   ` sashiko-bot
2026-08-16 12:47   ` Andy Yan
2026-08-16 12:47     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 05/21] drm/bridge: synopsys: dw-dp: Add missing mutex cleanups on module removal Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:30   ` sashiko-bot
2026-08-16 12:49   ` Andy Yan
2026-08-16 12:49     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 06/21] drm/bridge: synopsys: dw-dp: Fix AUX transfer timeout race condition Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:32   ` sashiko-bot
2026-08-16 12:52   ` Andy Yan
2026-08-16 12:52     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 07/21] drm/bridge: synopsys: dw-dp: Fix support for short I2C reads Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-16 12:54   ` Andy Yan
2026-08-16 12:54     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 08/21] drm/bridge: synopsys: dw-dp: Free output_fmts when none are valid Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-16 12:56   ` Andy Yan
2026-08-16 12:56     ` Andy Yan
2026-08-06 17:02 ` [PATCH v11 09/21] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:33   ` sashiko-bot
2026-08-06 17:02 ` [PATCH v11 10/21] drm/bridge: synopsys: dw-dp: Add follow-up bridge support Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-07  2:50   ` Chaoyi Chen
2026-08-07  2:50     ` Chaoyi Chen
2026-08-06 17:02 ` [PATCH v11 11/21] drm/bridge: Add out-of-band HPD notify handler Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 12/21] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 13/21] drm/rockchip: dw_dp: Implement out-of-band HPD handling Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:27   ` sashiko-bot
2026-08-06 17:02 ` [PATCH v11 14/21] drm/bridge: synopsys: dw-dp: Add Runtime PM support Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:41   ` sashiko-bot
2026-08-06 17:02 ` [PATCH v11 15/21] drm/rockchip: dw_dp: Add runtime " Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:45   ` sashiko-bot
2026-08-06 17:02 ` [PATCH v11 16/21] drm/bridge: synopsys: dw-dp: Protect sdp_reg_bank from concurrent access Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 17/21] drm/bridge: synopsys: dw-dp: Drop useless reservation of first slot Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:45   ` sashiko-bot
2026-08-06 17:02 ` [PATCH v11 18/21] drm/bridge: synopsys: dw-dp: Clear only enabled SDPs on atomic disable Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 19/21] drm/bridge: synopsys: dw-dp: Use regmap_set_bits in dw_dp_send_sdp Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 20/21] dt-bindings: display: rockchip: dw-dp: Fix sound DAI cells Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:39   ` sashiko-bot
2026-08-07 15:51     ` Rob Herring
2026-08-07 17:58       ` Sebastian Reichel
2026-08-06 17:02 ` [PATCH v11 21/21] drm/bridge: synopsys: dw-dp: Add audio support Sebastian Reichel
2026-08-06 17:02   ` Sebastian Reichel
2026-08-06 17:44   ` sashiko-bot
2026-08-08  9:41 ` [PATCH v11 00/21] Synopsys DisplayPort Controller improvements for Rockchip platforms Igor Paunovic
2026-08-08  9:41   ` Igor Paunovic
2026-08-08 20:19   ` Sebastian Reichel
2026-08-08 20:19     ` Sebastian Reichel
2026-08-10 11:48 ` Heiko Stübner
2026-08-10 11:48   ` Heiko Stübner
2026-08-10 12:08   ` Alexey Charkov
2026-08-10 12:08     ` Alexey Charkov
2026-08-11 21:15   ` Igor Paunovic
2026-08-11 21:15     ` Igor Paunovic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=78ac4580.18bf.1a00a976aac.Coremail.andyshrk@163.com \
    --to=andyshrk@163.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=alchark@flipper.net \
    --cc=andrzej.hajda@intel.com \
    --cc=andy.yan@rock-chips.com \
    --cc=conor+dt@kernel.org \
    --cc=cristian.ciocaltea@collabora.com \
    --cc=damon.ding@rock-chips.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=kernel@collabora.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=lumag@kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=neil.armstrong@linaro.org \
    --cc=p.zabel@pengutronix.de \
    --cc=rfoss@kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-bot@kernel.org \
    --cc=sebastian.reichel@collabora.com \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.