Skip to content

Commit 152cce0

Browse files
mszyprowmripard
authored andcommitted
drm/bridge: analogix_dp: Split bind() into probe() and real bind()
Analogix_dp driver acquires all its resources in the ->bind() callback, what is a bit against the component driver based approach, where the driver initialization is split into a probe(), where all resources are gathered, and a bind(), where all objects are created and a compound driver is initialized. Extract all the resource related operations to analogix_dp_probe() and analogix_dp_remove(), then call them before/after registration of the device components from the main Exynos DP and Rockchip DP drivers. Also move the plat_data initialization to the probe() to make it available for the analogix_dp_probe() function. This fixes the multiple calls to the bind() of the DRM compound driver when the DP PHY driver is not yet loaded/probed: [drm] Exynos DRM: using 14400000.fimd device for DMA mapping operations exynos-drm exynos-drm: bound 14400000.fimd (ops fimd_component_ops [exynosdrm]) exynos-drm exynos-drm: bound 14450000.mixer (ops mixer_component_ops [exynosdrm]) exynos-dp 145b000.dp-controller: no DP phy configured exynos-drm exynos-drm: failed to bind 145b000.dp-controller (ops exynos_dp_ops [exynosdrm]): -517 exynos-drm exynos-drm: master bind failed: -517 ... [drm] Exynos DRM: using 14400000.fimd device for DMA mapping operations exynos-drm exynos-drm: bound 14400000.fimd (ops hdmi_enable [exynosdrm]) exynos-drm exynos-drm: bound 14450000.mixer (ops hdmi_enable [exynosdrm]) exynos-drm exynos-drm: bound 145b000.dp-controller (ops hdmi_enable [exynosdrm]) exynos-drm exynos-drm: bound 14530000.hdmi (ops hdmi_enable [exynosdrm]) [drm] Supports vblank timestamp caching Rev 2 (21.10.2013). Console: switching to colour frame buffer device 170x48 exynos-drm exynos-drm: fb0: exynosdrmfb frame buffer device [drm] Initialized exynos 1.1.0 20180330 for exynos-drm on minor 1 ... Signed-off-by: Marek Szyprowski <[email protected]> Acked-by: Andy Yan <[email protected]> Reviewed-by: Andrzej Hajda <[email protected]> Signed-off-by: Andrzej Hajda <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 83a1967) Signed-off-by: Maxime Ripard <[email protected]>
1 parent b2ecb89 commit 152cce0

File tree

4 files changed

+61
-42
lines changed

4 files changed

+61
-42
lines changed

drivers/gpu/drm/bridge/analogix/analogix_dp_core.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,8 +1652,7 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
16521652
}
16531653

16541654
struct analogix_dp_device *
1655-
analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1656-
struct analogix_dp_plat_data *plat_data)
1655+
analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
16571656
{
16581657
struct platform_device *pdev = to_platform_device(dev);
16591658
struct analogix_dp_device *dp;
@@ -1756,36 +1755,43 @@ analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
17561755
irq_flags, "analogix-dp", dp);
17571756
if (ret) {
17581757
dev_err(&pdev->dev, "failed to request irq\n");
1759-
goto err_disable_pm_runtime;
1758+
return ERR_PTR(ret);
17601759
}
17611760
disable_irq(dp->irq);
17621761

1762+
return dp;
1763+
}
1764+
EXPORT_SYMBOL_GPL(analogix_dp_probe);
1765+
1766+
int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
1767+
{
1768+
int ret;
1769+
17631770
dp->drm_dev = drm_dev;
17641771
dp->encoder = dp->plat_data->encoder;
17651772

17661773
dp->aux.name = "DP-AUX";
17671774
dp->aux.transfer = analogix_dpaux_transfer;
1768-
dp->aux.dev = &pdev->dev;
1775+
dp->aux.dev = dp->dev;
17691776

17701777
ret = drm_dp_aux_register(&dp->aux);
17711778
if (ret)
1772-
return ERR_PTR(ret);
1779+
return ret;
17731780

1774-
pm_runtime_enable(dev);
1781+
pm_runtime_enable(dp->dev);
17751782

17761783
ret = analogix_dp_create_bridge(drm_dev, dp);
17771784
if (ret) {
17781785
DRM_ERROR("failed to create bridge (%d)\n", ret);
17791786
goto err_disable_pm_runtime;
17801787
}
17811788

1782-
return dp;
1789+
return 0;
17831790

17841791
err_disable_pm_runtime:
1792+
pm_runtime_disable(dp->dev);
17851793

1786-
pm_runtime_disable(dev);
1787-
1788-
return ERR_PTR(ret);
1794+
return ret;
17891795
}
17901796
EXPORT_SYMBOL_GPL(analogix_dp_bind);
17911797

@@ -1802,10 +1808,15 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
18021808

18031809
drm_dp_aux_unregister(&dp->aux);
18041810
pm_runtime_disable(dp->dev);
1805-
clk_disable_unprepare(dp->clock);
18061811
}
18071812
EXPORT_SYMBOL_GPL(analogix_dp_unbind);
18081813

1814+
void analogix_dp_remove(struct analogix_dp_device *dp)
1815+
{
1816+
clk_disable_unprepare(dp->clock);
1817+
}
1818+
EXPORT_SYMBOL_GPL(analogix_dp_remove);
1819+
18091820
#ifdef CONFIG_PM
18101821
int analogix_dp_suspend(struct analogix_dp_device *dp)
18111822
{

drivers/gpu/drm/exynos/exynos_dp.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,8 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
159159
struct drm_device *drm_dev = data;
160160
int ret;
161161

162-
dp->dev = dev;
163162
dp->drm_dev = drm_dev;
164163

165-
dp->plat_data.dev_type = EXYNOS_DP;
166-
dp->plat_data.power_on_start = exynos_dp_poweron;
167-
dp->plat_data.power_off = exynos_dp_poweroff;
168-
dp->plat_data.attach = exynos_dp_bridge_attach;
169-
dp->plat_data.get_modes = exynos_dp_get_modes;
170-
171164
if (!dp->plat_data.panel && !dp->ptn_bridge) {
172165
ret = exynos_dp_dt_parse_panel(dp);
173166
if (ret)
@@ -185,13 +178,11 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
185178

186179
dp->plat_data.encoder = encoder;
187180

188-
dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
189-
if (IS_ERR(dp->adp)) {
181+
ret = analogix_dp_bind(dp->adp, dp->drm_dev);
182+
if (ret)
190183
dp->encoder.funcs->destroy(&dp->encoder);
191-
return PTR_ERR(dp->adp);
192-
}
193184

194-
return 0;
185+
return ret;
195186
}
196187

197188
static void exynos_dp_unbind(struct device *dev, struct device *master,
@@ -222,6 +213,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
222213
if (!dp)
223214
return -ENOMEM;
224215

216+
dp->dev = dev;
225217
/*
226218
* We just use the drvdata until driver run into component
227219
* add function, and then we would set drvdata to null, so
@@ -247,16 +239,29 @@ static int exynos_dp_probe(struct platform_device *pdev)
247239

248240
/* The remote port can be either a panel or a bridge */
249241
dp->plat_data.panel = panel;
242+
dp->plat_data.dev_type = EXYNOS_DP;
243+
dp->plat_data.power_on_start = exynos_dp_poweron;
244+
dp->plat_data.power_off = exynos_dp_poweroff;
245+
dp->plat_data.attach = exynos_dp_bridge_attach;
246+
dp->plat_data.get_modes = exynos_dp_get_modes;
250247
dp->plat_data.skip_connector = !!bridge;
248+
251249
dp->ptn_bridge = bridge;
252250

253251
out:
252+
dp->adp = analogix_dp_probe(dev, &dp->plat_data);
253+
if (IS_ERR(dp->adp))
254+
return PTR_ERR(dp->adp);
255+
254256
return component_add(&pdev->dev, &exynos_dp_ops);
255257
}
256258

257259
static int exynos_dp_remove(struct platform_device *pdev)
258260
{
261+
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
262+
259263
component_del(&pdev->dev, &exynos_dp_ops);
264+
analogix_dp_remove(dp->adp);
260265

261266
return 0;
262267
}

drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,9 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
325325
void *data)
326326
{
327327
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
328-
const struct rockchip_dp_chip_data *dp_data;
329328
struct drm_device *drm_dev = data;
330329
int ret;
331330

332-
dp_data = of_device_get_match_data(dev);
333-
if (!dp_data)
334-
return -ENODEV;
335-
336-
dp->data = dp_data;
337331
dp->drm_dev = drm_dev;
338332

339333
ret = rockchip_dp_drm_create_encoder(dp);
@@ -344,16 +338,9 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
344338

345339
dp->plat_data.encoder = &dp->encoder;
346340

347-
dp->plat_data.dev_type = dp->data->chip_type;
348-
dp->plat_data.power_on_start = rockchip_dp_poweron_start;
349-
dp->plat_data.power_off = rockchip_dp_powerdown;
350-
dp->plat_data.get_modes = rockchip_dp_get_modes;
351-
352-
dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
353-
if (IS_ERR(dp->adp)) {
354-
ret = PTR_ERR(dp->adp);
341+
ret = analogix_dp_bind(dp->adp, drm_dev);
342+
if (ret)
355343
goto err_cleanup_encoder;
356-
}
357344

358345
return 0;
359346
err_cleanup_encoder:
@@ -368,8 +355,6 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
368355

369356
analogix_dp_unbind(dp->adp);
370357
dp->encoder.funcs->destroy(&dp->encoder);
371-
372-
dp->adp = ERR_PTR(-ENODEV);
373358
}
374359

375360
static const struct component_ops rockchip_dp_component_ops = {
@@ -380,10 +365,15 @@ static const struct component_ops rockchip_dp_component_ops = {
380365
static int rockchip_dp_probe(struct platform_device *pdev)
381366
{
382367
struct device *dev = &pdev->dev;
368+
const struct rockchip_dp_chip_data *dp_data;
383369
struct drm_panel *panel = NULL;
384370
struct rockchip_dp_device *dp;
385371
int ret;
386372

373+
dp_data = of_device_get_match_data(dev);
374+
if (!dp_data)
375+
return -ENODEV;
376+
387377
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
388378
if (ret < 0)
389379
return ret;
@@ -394,20 +384,32 @@ static int rockchip_dp_probe(struct platform_device *pdev)
394384

395385
dp->dev = dev;
396386
dp->adp = ERR_PTR(-ENODEV);
387+
dp->data = dp_data;
397388
dp->plat_data.panel = panel;
389+
dp->plat_data.dev_type = dp->data->chip_type;
390+
dp->plat_data.power_on_start = rockchip_dp_poweron_start;
391+
dp->plat_data.power_off = rockchip_dp_powerdown;
392+
dp->plat_data.get_modes = rockchip_dp_get_modes;
398393

399394
ret = rockchip_dp_of_probe(dp);
400395
if (ret < 0)
401396
return ret;
402397

403398
platform_set_drvdata(pdev, dp);
404399

400+
dp->adp = analogix_dp_probe(dev, &dp->plat_data);
401+
if (IS_ERR(dp->adp))
402+
return PTR_ERR(dp->adp);
403+
405404
return component_add(dev, &rockchip_dp_component_ops);
406405
}
407406

408407
static int rockchip_dp_remove(struct platform_device *pdev)
409408
{
409+
struct rockchip_dp_device *dp = platform_get_drvdata(pdev);
410+
410411
component_del(&pdev->dev, &rockchip_dp_component_ops);
412+
analogix_dp_remove(dp->adp);
411413

412414
return 0;
413415
}

include/drm/bridge/analogix_dp.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ int analogix_dp_resume(struct analogix_dp_device *dp);
4242
int analogix_dp_suspend(struct analogix_dp_device *dp);
4343

4444
struct analogix_dp_device *
45-
analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
46-
struct analogix_dp_plat_data *plat_data);
45+
analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data);
46+
int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev);
4747
void analogix_dp_unbind(struct analogix_dp_device *dp);
48+
void analogix_dp_remove(struct analogix_dp_device *dp);
4849

4950
int analogix_dp_start_crc(struct drm_connector *connector);
5051
int analogix_dp_stop_crc(struct drm_connector *connector);

0 commit comments

Comments
 (0)