Mediatek DRM Fixes for Linux 5.17
1. Avoid EPROBE_DEFER loop with external bridge -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJiDR5IAAoJEOHKc6PJWU4kzw4P/3EwRw7cb6IAVc5O19Wj+Juo c8ohK/tJUs0sgmnTAWJGiq+ELtqBoMnpYofAvgswexQ8rRrljcdYSlH3uAsJOs9l XZ+AlJXqh3rGDEf9CfFUj3Ni30CVAnwhDgBW0qXT7cm1F7JDafpPRB78sMnjVapZ bNRw8dhFpFMTUFZB3iokkwAXJL9OYBVTx4/8Bse3KQV3GzYPB1POOab7NRf9mEhx 8Ipzel4r7jTiaAqL/tGsO3kErDcVHnb9vHKqIsW4ciFv9elVECUfem9+kBkw1AXl 0HjEHnjdEU+Rv7snoMIDgXYHSUvVTgGEbX2xbz1+//tGGIJTXHSWYQ0cRr0O+02v KnsQZGxhn0IC/9TuZ5sXRmXxX+REdqkq9Updls46GXV2GqqaUzmSifzhuEVozidN KXUWojEYuipou1gX4YXbjy3wckdDZxsgmtz0ekPi5DV+OYxR1r5GdhxVSGEfHkGh 0JzIwmnwyX8SPBu4QbU0vz2l/zqIyDp84+DYGzW1ELlS50jZJPml97chVYOtEUhq GlrWbKq6rBDn3n4WCaRNADZa2keUOgajEUagLO+IPnAowZAnZxMH7iDjbRL+6wIZ E6CG6vBkWdHAIUNAdNiN3bO4v41Ac4Z+VCid9CApBTdYIUM+xmQ1G3t5BxrohH3I n51nYLbUlHf1xVr2/QyR =18wb -----END PGP SIGNATURE----- Merge tag 'mediatek-drm-fixes-5.17' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-fixes Mediatek DRM Fixes for Linux 5.17 1. Avoid EPROBE_DEFER loop with external bridge Signed-off-by: Dave Airlie <airlied@redhat.com> From: Chun-Kuang Hu <chunkuang.hu@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/1645027727-19554-1-git-send-email-chunkuang.hu@kernel.org
This commit is contained in:
commit
fb9c96714f
@ -786,15 +786,98 @@ void mtk_dsi_ddp_stop(struct device *dev)
|
||||
mtk_dsi_poweroff(dsi);
|
||||
}
|
||||
|
||||
static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_simple_encoder_init(drm, &dsi->encoder,
|
||||
DRM_MODE_ENCODER_DSI);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to encoder init to drm\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
|
||||
|
||||
ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
|
||||
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret)
|
||||
goto err_cleanup_encoder;
|
||||
|
||||
dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
|
||||
if (IS_ERR(dsi->connector)) {
|
||||
DRM_ERROR("Unable to create bridge connector\n");
|
||||
ret = PTR_ERR(dsi->connector);
|
||||
goto err_cleanup_encoder;
|
||||
}
|
||||
drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_encoder:
|
||||
drm_encoder_cleanup(&dsi->encoder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
int ret;
|
||||
struct drm_device *drm = data;
|
||||
struct mtk_dsi *dsi = dev_get_drvdata(dev);
|
||||
|
||||
ret = mtk_dsi_encoder_init(drm, dsi);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return device_reset_optional(dev);
|
||||
}
|
||||
|
||||
static void mtk_dsi_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct mtk_dsi *dsi = dev_get_drvdata(dev);
|
||||
|
||||
drm_encoder_cleanup(&dsi->encoder);
|
||||
}
|
||||
|
||||
static const struct component_ops mtk_dsi_component_ops = {
|
||||
.bind = mtk_dsi_bind,
|
||||
.unbind = mtk_dsi_unbind,
|
||||
};
|
||||
|
||||
static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *device)
|
||||
{
|
||||
struct mtk_dsi *dsi = host_to_dsi(host);
|
||||
struct device *dev = host->dev;
|
||||
int ret;
|
||||
|
||||
dsi->lanes = device->lanes;
|
||||
dsi->format = device->format;
|
||||
dsi->mode_flags = device->mode_flags;
|
||||
dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
|
||||
if (IS_ERR(dsi->next_bridge))
|
||||
return PTR_ERR(dsi->next_bridge);
|
||||
|
||||
drm_bridge_add(&dsi->bridge);
|
||||
|
||||
ret = component_add(host->dev, &mtk_dsi_component_ops);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to add dsi_host component: %d\n", ret);
|
||||
drm_bridge_remove(&dsi->bridge);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *device)
|
||||
{
|
||||
struct mtk_dsi *dsi = host_to_dsi(host);
|
||||
|
||||
component_del(host->dev, &mtk_dsi_component_ops);
|
||||
drm_bridge_remove(&dsi->bridge);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
|
||||
static const struct mipi_dsi_host_ops mtk_dsi_ops = {
|
||||
.attach = mtk_dsi_host_attach,
|
||||
.detach = mtk_dsi_host_detach,
|
||||
.transfer = mtk_dsi_host_transfer,
|
||||
};
|
||||
|
||||
static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_simple_encoder_init(drm, &dsi->encoder,
|
||||
DRM_MODE_ENCODER_DSI);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to encoder init to drm\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
|
||||
|
||||
ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
|
||||
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret)
|
||||
goto err_cleanup_encoder;
|
||||
|
||||
dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
|
||||
if (IS_ERR(dsi->connector)) {
|
||||
DRM_ERROR("Unable to create bridge connector\n");
|
||||
ret = PTR_ERR(dsi->connector);
|
||||
goto err_cleanup_encoder;
|
||||
}
|
||||
drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_encoder:
|
||||
drm_encoder_cleanup(&dsi->encoder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
int ret;
|
||||
struct drm_device *drm = data;
|
||||
struct mtk_dsi *dsi = dev_get_drvdata(dev);
|
||||
|
||||
ret = mtk_dsi_encoder_init(drm, dsi);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return device_reset_optional(dev);
|
||||
}
|
||||
|
||||
static void mtk_dsi_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct mtk_dsi *dsi = dev_get_drvdata(dev);
|
||||
|
||||
drm_encoder_cleanup(&dsi->encoder);
|
||||
}
|
||||
|
||||
static const struct component_ops mtk_dsi_component_ops = {
|
||||
.bind = mtk_dsi_bind,
|
||||
.unbind = mtk_dsi_unbind,
|
||||
};
|
||||
|
||||
static int mtk_dsi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_dsi *dsi;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct drm_panel *panel;
|
||||
struct resource *regs;
|
||||
int irq_num;
|
||||
int ret;
|
||||
@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
|
||||
&panel, &dsi->next_bridge);
|
||||
if (ret)
|
||||
goto err_unregister_host;
|
||||
|
||||
if (panel) {
|
||||
dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
|
||||
if (IS_ERR(dsi->next_bridge)) {
|
||||
ret = PTR_ERR(dsi->next_bridge);
|
||||
goto err_unregister_host;
|
||||
}
|
||||
}
|
||||
|
||||
dsi->driver_data = of_device_get_match_data(dev);
|
||||
|
||||
dsi->engine_clk = devm_clk_get(dev, "engine");
|
||||
@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
|
||||
dsi->bridge.of_node = dev->of_node;
|
||||
dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
|
||||
|
||||
drm_bridge_add(&dsi->bridge);
|
||||
|
||||
ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add component: %d\n", ret);
|
||||
goto err_unregister_host;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_host:
|
||||
@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
|
||||
struct mtk_dsi *dsi = platform_get_drvdata(pdev);
|
||||
|
||||
mtk_output_dsi_disable(dsi);
|
||||
drm_bridge_remove(&dsi->bridge);
|
||||
component_del(&pdev->dev, &mtk_dsi_component_ops);
|
||||
mipi_dsi_host_unregister(&dsi->host);
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user