Unverified Commit e74b84cd authored by Luca Ceresoli's avatar Luca Ceresoli Committed by Louis Chauvet
Browse files

drm/bridge: imx8*-ldb: convert to devm_drm_bridge_alloc() API



This is the new API for allocating DRM bridges.

These two drivers are tangled together by the ldb_add_bridge_helper(), so
they are converted at once.

They also have a similar design, each embedding an array of channels in
their main struct, and each channel embeds a drm_bridge. This prevents
dynamic, refcount-based deallocation of the bridges.

To make the new, dynamic bridge allocation possible:

 * change the array of channels into an array of channel pointers
 * allocate each channel using devm_drm_bridge_alloc()
 * adapt ldb_add_bridge_helper() to not set the funcs pointer
   (now done by devm_drm_bridge_alloc())
 * adapt the code wherever using the channels

Signed-off-by: default avatarLuca Ceresoli <luca.ceresoli@bootlin.com>
Acked-by: default avatarLiu Ying <victor.liu@nxp.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250424-drm-bridge-convert-to-alloc-api-v2-31-8f91a404d86b@bootlin.com


Signed-off-by: default avatarLouis Chauvet <louis.chauvet@bootlin.com>
parent 9545c91e
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -190,8 +190,7 @@ int ldb_find_next_bridge_helper(struct ldb *ldb)
}
EXPORT_SYMBOL_GPL(ldb_find_next_bridge_helper);

void ldb_add_bridge_helper(struct ldb *ldb,
			   const struct drm_bridge_funcs *bridge_funcs)
void ldb_add_bridge_helper(struct ldb *ldb)
{
	struct ldb_channel *ldb_ch;
	int i;
@@ -203,7 +202,6 @@ void ldb_add_bridge_helper(struct ldb *ldb,
			continue;

		ldb_ch->bridge.driver_private = ldb_ch;
		ldb_ch->bridge.funcs = bridge_funcs;
		ldb_ch->bridge.of_node = ldb_ch->np;

		drm_bridge_add(&ldb_ch->bridge);
+1 −2
Original line number Diff line number Diff line
@@ -88,8 +88,7 @@ int ldb_init_helper(struct ldb *ldb);

int ldb_find_next_bridge_helper(struct ldb *ldb);

void ldb_add_bridge_helper(struct ldb *ldb,
			   const struct drm_bridge_funcs *bridge_funcs);
void ldb_add_bridge_helper(struct ldb *ldb);

void ldb_remove_bridge_helper(struct ldb *ldb);

+20 −12
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct imx8qm_ldb_channel {
struct imx8qm_ldb {
	struct ldb base;
	struct device *dev;
	struct imx8qm_ldb_channel channel[MAX_LDB_CHAN_NUM];
	struct imx8qm_ldb_channel *channel[MAX_LDB_CHAN_NUM];
	struct clk *clk_pixel;
	struct clk *clk_bypass;
	int active_chno;
@@ -107,7 +107,7 @@ static int imx8qm_ldb_bridge_atomic_check(struct drm_bridge *bridge,

	if (is_split) {
		imx8qm_ldb_ch =
			&imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1];
			imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1];
		imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, true,
				       phy_cfg);
		ret = phy_validate(imx8qm_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts);
@@ -158,7 +158,7 @@ imx8qm_ldb_bridge_mode_set(struct drm_bridge *bridge,

	if (is_split) {
		imx8qm_ldb_ch =
			&imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1];
			imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1];
		imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, true,
				       phy_cfg);
		ret = phy_configure(imx8qm_ldb_ch->phy, &opts);
@@ -226,13 +226,13 @@ static void imx8qm_ldb_bridge_atomic_enable(struct drm_bridge *bridge,
	}

	if (is_split) {
		ret = phy_power_on(imx8qm_ldb->channel[0].phy);
		ret = phy_power_on(imx8qm_ldb->channel[0]->phy);
		if (ret)
			DRM_DEV_ERROR(dev,
				      "failed to power on channel0 PHY: %d\n",
				      ret);

		ret = phy_power_on(imx8qm_ldb->channel[1].phy);
		ret = phy_power_on(imx8qm_ldb->channel[1]->phy);
		if (ret)
			DRM_DEV_ERROR(dev,
				      "failed to power on channel1 PHY: %d\n",
@@ -261,12 +261,12 @@ static void imx8qm_ldb_bridge_atomic_disable(struct drm_bridge *bridge,
	ldb_bridge_disable_helper(bridge);

	if (is_split) {
		ret = phy_power_off(imx8qm_ldb->channel[0].phy);
		ret = phy_power_off(imx8qm_ldb->channel[0]->phy);
		if (ret)
			DRM_DEV_ERROR(dev,
				      "failed to power off channel0 PHY: %d\n",
				      ret);
		ret = phy_power_off(imx8qm_ldb->channel[1].phy);
		ret = phy_power_off(imx8qm_ldb->channel[1]->phy);
		if (ret)
			DRM_DEV_ERROR(dev,
				      "failed to power off channel1 PHY: %d\n",
@@ -412,7 +412,7 @@ static int imx8qm_ldb_get_phy(struct imx8qm_ldb *imx8qm_ldb)
	int i, ret;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		imx8qm_ldb_ch = &imx8qm_ldb->channel[i];
		imx8qm_ldb_ch = imx8qm_ldb->channel[i];
		ldb_ch = &imx8qm_ldb_ch->base;

		if (!ldb_ch->is_available)
@@ -448,6 +448,14 @@ static int imx8qm_ldb_probe(struct platform_device *pdev)
	if (!imx8qm_ldb)
		return -ENOMEM;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		imx8qm_ldb->channel[i] =
			devm_drm_bridge_alloc(dev, struct imx8qm_ldb_channel, base.bridge,
					      &imx8qm_ldb_bridge_funcs);
		if (IS_ERR(imx8qm_ldb->channel[i]))
			return PTR_ERR(imx8qm_ldb->channel[i]);
	}

	imx8qm_ldb->clk_pixel = devm_clk_get(dev, "pixel");
	if (IS_ERR(imx8qm_ldb->clk_pixel)) {
		ret = PTR_ERR(imx8qm_ldb->clk_pixel);
@@ -473,7 +481,7 @@ static int imx8qm_ldb_probe(struct platform_device *pdev)
	ldb->ctrl_reg = 0xe0;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++)
		ldb->channel[i] = &imx8qm_ldb->channel[i].base;
		ldb->channel[i] = &imx8qm_ldb->channel[i]->base;

	ret = ldb_init_helper(ldb);
	if (ret)
@@ -499,12 +507,12 @@ static int imx8qm_ldb_probe(struct platform_device *pdev)
		}

		imx8qm_ldb->active_chno = 0;
		imx8qm_ldb_ch = &imx8qm_ldb->channel[0];
		imx8qm_ldb_ch = imx8qm_ldb->channel[0];
		ldb_ch = &imx8qm_ldb_ch->base;
		ldb_ch->link_type = pixel_order;
	} else {
		for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
			imx8qm_ldb_ch = &imx8qm_ldb->channel[i];
			imx8qm_ldb_ch = imx8qm_ldb->channel[i];
			ldb_ch = &imx8qm_ldb_ch->base;

			if (ldb_ch->is_available) {
@@ -525,7 +533,7 @@ static int imx8qm_ldb_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, imx8qm_ldb);
	pm_runtime_enable(dev);

	ldb_add_bridge_helper(ldb, &imx8qm_ldb_bridge_funcs);
	ldb_add_bridge_helper(ldb);

	return ret;
}
+14 −6
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ struct imx8qxp_ldb_channel {
struct imx8qxp_ldb {
	struct ldb base;
	struct device *dev;
	struct imx8qxp_ldb_channel channel[MAX_LDB_CHAN_NUM];
	struct imx8qxp_ldb_channel *channel[MAX_LDB_CHAN_NUM];
	struct clk *clk_pixel;
	struct clk *clk_bypass;
	struct drm_bridge *companion;
@@ -410,7 +410,7 @@ static const struct drm_bridge_funcs imx8qxp_ldb_bridge_funcs = {
static int imx8qxp_ldb_set_di_id(struct imx8qxp_ldb *imx8qxp_ldb)
{
	struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
			 &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
			 imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
	struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base;
	struct device_node *ep, *remote;
	struct device *dev = imx8qxp_ldb->dev;
@@ -456,7 +456,7 @@ imx8qxp_ldb_check_chno_and_dual_link(struct ldb_channel *ldb_ch, int link)
static int imx8qxp_ldb_parse_dt_companion(struct imx8qxp_ldb *imx8qxp_ldb)
{
	struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
			 &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
			 imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
	struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base;
	struct ldb_channel *companion_ldb_ch;
	struct device_node *companion;
@@ -586,6 +586,14 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev)
	if (!imx8qxp_ldb)
		return -ENOMEM;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		imx8qxp_ldb->channel[i] =
			devm_drm_bridge_alloc(dev, struct imx8qxp_ldb_channel, base.bridge,
					      &imx8qxp_ldb_bridge_funcs);
		if (IS_ERR(imx8qxp_ldb->channel[i]))
			return PTR_ERR(imx8qxp_ldb->channel[i]);
	}

	imx8qxp_ldb->clk_pixel = devm_clk_get(dev, "pixel");
	if (IS_ERR(imx8qxp_ldb->clk_pixel)) {
		ret = PTR_ERR(imx8qxp_ldb->clk_pixel);
@@ -611,7 +619,7 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev)
	ldb->ctrl_reg = 0xe0;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++)
		ldb->channel[i] = &imx8qxp_ldb->channel[i].base;
		ldb->channel[i] = &imx8qxp_ldb->channel[i]->base;

	ret = ldb_init_helper(ldb);
	if (ret)
@@ -627,7 +635,7 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev)
	}

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		imx8qxp_ldb_ch = &imx8qxp_ldb->channel[i];
		imx8qxp_ldb_ch = imx8qxp_ldb->channel[i];
		ldb_ch = &imx8qxp_ldb_ch->base;

		if (ldb_ch->is_available) {
@@ -660,7 +668,7 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, imx8qxp_ldb);
	pm_runtime_enable(dev);

	ldb_add_bridge_helper(ldb, &imx8qxp_ldb_bridge_funcs);
	ldb_add_bridge_helper(ldb);

	return 0;
}