From da3b3f107564030807f52311416ee6826e05fa93 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Fri, 11 Sep 2020 15:54:11 +0200 Subject: drm/exynos: add API functions for platform drivers Add new functions for the probe/remove API, the bind/unbind API and resume/suspend calls. Move everything exynos drm specific into separate functions, which can easily be moved to other files. Also split struct exynos_dsi into a generic and a platform specific struct. Signed-off-by: Michael Tretter --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 114 +++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 5fae3395e245..163998825f6f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -265,7 +265,6 @@ struct exynos_dsi_driver_data { }; struct exynos_dsi { - struct drm_encoder encoder; struct drm_bridge bridge; struct mipi_dsi_host dsi_host; struct drm_connector connector; @@ -419,6 +418,11 @@ enum reg_value_idx { PHYTIMING_HS_TRAIL }; +struct exynos_dsi_pltfm { + struct exynos_dsi *dsi; + struct drm_encoder encoder; +}; + static const unsigned int reg_values[] = { [RESET_TYPE] = DSIM_SWRST, [PLL_TIMER] = 500, @@ -476,7 +480,7 @@ static const unsigned int exynos5433_reg_values[] = { static int __exynos_dsi_host_attach(struct device *dev, struct mipi_dsi_device *device) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); struct drm_device *drm = dsi->encoder.dev; struct exynos_drm_crtc *crtc; @@ -494,7 +498,7 @@ static int __exynos_dsi_host_attach(struct device *dev, static int __exynos_dsi_host_detach(struct device *dev, struct mipi_dsi_device *device) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); struct drm_device *drm = dsi->encoder.dev; if (drm->mode_config.poll_enabled) @@ -505,7 +509,7 @@ static int __exynos_dsi_host_detach(struct device *dev, static void __exynos_dsi_te_handler(struct device *dev) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); exynos_drm_crtc_te_handler(dsi->encoder.crtc); } @@ -1803,10 +1807,12 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) return 0; } -static int exynos_dsi_bind(struct device *dev, struct device *master, - void *data) +static int exynos_dsi_bind(struct exynos_dsi *dsi, struct drm_encoder *encoder); +static void exynos_dsi_unbind(struct exynos_dsi *dsi); + +static int exynos_dsi_pltfm_bind(struct device *dev, struct device *master, void *data) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); struct drm_encoder *encoder = &dsi->encoder; struct drm_device *drm_dev = data; struct device_node *in_bridge_node; @@ -1827,7 +1833,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, of_node_put(in_bridge_node); } - ret = drm_bridge_attach(encoder, &dsi->bridge, in_bridge, 0); + ret = exynos_dsi_bind(dsi->dsi, encoder); if (ret) goto err; @@ -1838,20 +1844,20 @@ err: return ret; } -static void exynos_dsi_unbind(struct device *dev, struct device *master, - void *data) +static void exynos_dsi_pltfm_unbind(struct device *dev, struct device *master, + void *data) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); struct drm_encoder *encoder = &dsi->encoder; - exynos_dsi_disable(dsi); + exynos_dsi_unbind(dsi->dsi); drm_encoder_cleanup(encoder); } -static const struct component_ops exynos_dsi_component_ops = { - .bind = exynos_dsi_bind, - .unbind = exynos_dsi_unbind, +static const struct component_ops exynos_dsi_pltfm_component_ops = { + .bind = exynos_dsi_pltfm_bind, + .unbind = exynos_dsi_pltfm_unbind, }; static struct exynos_dsi *__exynos_dsi_probe(struct platform_device *pdev) @@ -1957,20 +1963,52 @@ static void __exynos_dsi_remove(struct exynos_dsi *dsi) mipi_dsi_host_unregister(&dsi->dsi_host); } -static int exynos_dsi_probe(struct platform_device *pdev) +/* + * Probe/remove API, used from platforms based on the DRM bridge API. + */ +static struct exynos_dsi *exynos_dsi_probe(struct platform_device *pdev) { - struct exynos_dsi *dsi; + return __exynos_dsi_probe(pdev); +} + +static void exynos_dsi_remove(struct exynos_dsi *dsi) +{ + return __exynos_dsi_remove(dsi); +} + +/* + * Bind/unbind API, used from platforms based on the component framework. + */ +static int exynos_dsi_bind(struct exynos_dsi *dsi, struct drm_encoder *encoder) +{ + struct drm_bridge *previous = drm_bridge_chain_get_first_bridge(encoder); + + return drm_bridge_attach(encoder, &dsi->bridge, previous, 0); +} + +static void exynos_dsi_unbind(struct exynos_dsi *dsi) +{ + exynos_dsi_disable(dsi); +} + +static int exynos_dsi_pltfm_probe(struct platform_device *pdev) +{ + struct exynos_dsi_pltfm *dsi; struct device *dev = &pdev->dev; int ret; - dsi = __exynos_dsi_probe(pdev); - if (IS_ERR(dsi)) - return PTR_ERR(dsi); + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; platform_set_drvdata(pdev, dsi); + dsi->dsi = exynos_dsi_probe(pdev); + if (IS_ERR(dsi->dsi)) + return PTR_ERR(dsi->dsi); + pm_runtime_enable(dev); - ret = component_add(dev, &exynos_dsi_component_ops); + ret = component_add(dev, &exynos_dsi_pltfm_component_ops); if (ret) goto err_disable_runtime; @@ -1982,22 +2020,21 @@ err_disable_runtime: return ret; } -static int exynos_dsi_remove(struct platform_device *pdev) +static int exynos_dsi_pltfm_remove(struct platform_device *pdev) { - struct exynos_dsi *dsi = platform_get_drvdata(pdev); + struct exynos_dsi_pltfm *dsi = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - __exynos_dsi_remove(dsi); + exynos_dsi_remove(dsi->dsi); - component_del(&pdev->dev, &exynos_dsi_component_ops); + component_del(&pdev->dev, &exynos_dsi_pltfm_component_ops); return 0; } -static int __maybe_unused exynos_dsi_suspend(struct device *dev) +static int exynos_dsi_suspend(struct exynos_dsi *dsi) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; int ret, i; @@ -2025,9 +2062,8 @@ static int __maybe_unused exynos_dsi_suspend(struct device *dev) return 0; } -static int __maybe_unused exynos_dsi_resume(struct device *dev) +static int exynos_dsi_resume(struct exynos_dsi *dsi) { - struct exynos_dsi *dsi = dev_get_drvdata(dev); const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; int ret, i; @@ -2059,15 +2095,29 @@ err_clk: return ret; } +static int __maybe_unused exynos_dsi_pltfm_suspend(struct device *dev) +{ + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); + + return exynos_dsi_suspend(dsi->dsi); +} + +static int __maybe_unused exynos_dsi_pltfm_resume(struct device *dev) +{ + struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev); + + return exynos_dsi_resume(dsi->dsi); +} + static const struct dev_pm_ops exynos_dsi_pm_ops = { - SET_RUNTIME_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume, NULL) + SET_RUNTIME_PM_OPS(exynos_dsi_pltfm_suspend, exynos_dsi_pltfm_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; struct platform_driver dsi_driver = { - .probe = exynos_dsi_probe, - .remove = exynos_dsi_remove, + .probe = exynos_dsi_pltfm_probe, + .remove = exynos_dsi_pltfm_remove, .driver = { .name = "exynos-dsi", .owner = THIS_MODULE, -- cgit v1.2.3