From 8b5f7a62464a24cb83d6290c01d6cf9c8871774a Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 25 Jun 2018 14:03:01 +0200 Subject: drm: of: Export and rename drm_crtc_port_mask() Function is useful when drm_of_find_possible_crtcs() can't be used and custom parsing is needed. This can happen for example when there is a node with multiple muxes between crtc and encoder. Reviewed-by: Sean Paul Signed-off-by: Jernej Skrabec [maxime: change the function to have a consistent prefix] Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180625120304.7543-22-jernej.skrabec@siol.net --- drivers/gpu/drm/drm_of.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/drm_of.c') diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 1fe122461298..3b8c7a6a5720 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -15,15 +15,15 @@ static void drm_release_of(struct device *dev, void *data) } /** - * drm_crtc_port_mask - find the mask of a registered CRTC by port OF node + * drm_of_crtc_port_mask - find the mask of a registered CRTC by port OF node * @dev: DRM device * @port: port OF node * * Given a port OF node, return the possible mask of the corresponding * CRTC within a device's list of CRTCs. Returns zero if not found. */ -static uint32_t drm_crtc_port_mask(struct drm_device *dev, - struct device_node *port) +uint32_t drm_of_crtc_port_mask(struct drm_device *dev, + struct device_node *port) { unsigned int index = 0; struct drm_crtc *tmp; @@ -37,6 +37,7 @@ static uint32_t drm_crtc_port_mask(struct drm_device *dev, return 0; } +EXPORT_SYMBOL(drm_of_crtc_port_mask); /** * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port @@ -62,7 +63,7 @@ uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, return 0; } - possible_crtcs |= drm_crtc_port_mask(dev, remote_port); + possible_crtcs |= drm_of_crtc_port_mask(dev, remote_port); of_node_put(remote_port); } -- cgit From 5fa8e4a22182df8ea39adeba4bd518506e26a96d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 9 May 2018 15:00:39 +0200 Subject: drm/panel: Make of_drm_find_panel() return an ERR_PTR() instead of NULL Right now, the DRM panel logic returns NULL when a panel pointing to the passed OF node is not present in the list of registered panels. Most drivers interpret this NULL value as -EPROBE_DEFER, but we are about to modify the semantic of of_drm_find_panel() and let the framework return -ENODEV when the device node we're pointing to has a status property that is not equal to "okay" or "ok". Let's first patch the of_drm_find_panel() implementation to return ERR_PTR(-EPROBE_DEFER) instead of NULL and patch all callers to replace the '!panel' check by an 'IS_ERR(panel)' one. Signed-off-by: Boris Brezillon Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180509130042.9435-2-boris.brezillon@bootlin.com --- drivers/gpu/drm/bridge/cdns-dsi.c | 2 +- drivers/gpu/drm/bridge/lvds-encoder.c | 4 ++-- drivers/gpu/drm/drm_of.c | 4 +++- drivers/gpu/drm/drm_panel.c | 6 ++++-- drivers/gpu/drm/exynos/exynos_dp.c | 6 ++++-- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 4 ++-- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 3 +++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 5 +++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 4 ++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c | 5 ++++- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- drivers/gpu/drm/rcar-du/rcar_lvds.c | 4 ++-- drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 2 +- drivers/gpu/drm/sti/sti_dvo.c | 4 +++- drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 4 ++-- drivers/gpu/drm/tegra/dsi.c | 3 +++ drivers/gpu/drm/tegra/output.c | 4 ++-- include/drm/drm_panel.h | 2 +- 18 files changed, 43 insertions(+), 25 deletions(-) (limited to 'drivers/gpu/drm/drm_of.c') diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c index f2d43f24acfb..ce9496d13986 100644 --- a/drivers/gpu/drm/bridge/cdns-dsi.c +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -1152,7 +1152,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, np = of_node_get(dev->dev.of_node); panel = of_drm_find_panel(np); - if (panel) { + if (!IS_ERR(panel)) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI); } else { bridge = of_drm_find_bridge(dev->dev.of_node); diff --git a/drivers/gpu/drm/bridge/lvds-encoder.c b/drivers/gpu/drm/bridge/lvds-encoder.c index 75b0d3f6e4de..f56c92f7af7c 100644 --- a/drivers/gpu/drm/bridge/lvds-encoder.c +++ b/drivers/gpu/drm/bridge/lvds-encoder.c @@ -68,9 +68,9 @@ static int lvds_encoder_probe(struct platform_device *pdev) panel = of_drm_find_panel(panel_node); of_node_put(panel_node); - if (!panel) { + if (IS_ERR(panel)) { dev_dbg(&pdev->dev, "panel not found, deferring probe\n"); - return -EPROBE_DEFER; + return PTR_ERR(panel); } lvds_encoder->panel_bridge = diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 3b8c7a6a5720..1f4a16772583 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -241,8 +241,10 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, if (panel) { *panel = of_drm_find_panel(remote); - if (*panel) + if (!IS_ERR(*panel)) ret = 0; + else + *panel = NULL; } /* No panel found yet, check for a bridge next. */ diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index 965530a6f4cd..7e5530a04846 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c @@ -151,7 +151,9 @@ EXPORT_SYMBOL(drm_panel_detach); * tree node. If a matching panel is found, return a pointer to it. * * Return: A pointer to the panel registered for the specified device tree - * node or NULL if no panel matching the device tree node can be found. + * node or an ERR_PTR() if no panel matching the device tree node can be found. + * The only error that can be reported is -EPROBE_DEFER, meaning that the panel + * device has not been probed yet, and the caller should retry later. */ struct drm_panel *of_drm_find_panel(const struct device_node *np) { @@ -167,7 +169,7 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np) } mutex_unlock(&panel_lock); - return NULL; + return ERR_PTR(-EPROBE_DEFER); } EXPORT_SYMBOL(of_drm_find_panel); #endif diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 86330f396784..af7ab1ceb50f 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -232,9 +232,11 @@ static int exynos_dp_probe(struct platform_device *pdev) np = of_parse_phandle(dev->of_node, "panel", 0); if (np) { dp->plat_data.panel = of_drm_find_panel(np); + of_node_put(np); - if (!dp->plat_data.panel) - return -EPROBE_DEFER; + if (IS_ERR(dp->plat_data.panel)) + return PTR_ERR(dp->plat_data.panel); + goto out; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 66945e0dc57f..5887e8522b70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -240,8 +240,8 @@ struct drm_encoder *exynos_dpi_probe(struct device *dev) if (ctx->panel_node) { ctx->panel = of_drm_find_panel(ctx->panel_node); - if (!ctx->panel) - return ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(ctx->panel)) + return ERR_CAST(ctx->panel); } return &ctx->encoder; diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 6d29777884f9..809e1e0447df 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1519,6 +1519,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, dsi->format = device->format; dsi->mode_flags = device->mode_flags; dsi->panel = of_drm_find_panel(device->dev.of_node); + if (IS_ERR(dsi->panel)) + dsi->panel = NULL; + if (dsi->panel) { drm_panel_attach(dsi->panel, &dsi->connector); dsi->connector.status = connector_status_connected; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c index c54806d08dd7..681e2a07d03b 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c @@ -148,8 +148,9 @@ int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev) if (panel_node) { fsl_dev->connector.panel = of_drm_find_panel(panel_node); of_node_put(panel_node); - if (!fsl_dev->connector.panel) - return -EPROBE_DEFER; + if (IS_ERR(fsl_dev->connector.panel)) + return PTR_ERR(fsl_dev->connector.panel); + return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel); } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 4a645926edb7..2bfb39082f54 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -341,7 +341,7 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (panel) { + if (!IS_ERR(panel)) { drm_panel_disable(panel); drm_panel_unprepare(panel); } @@ -410,7 +410,7 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (panel) { + if (!IS_ERR(panel)) { drm_panel_prepare(panel); drm_panel_enable(panel); } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c index e3b1c86b7aae..32fba5664b0e 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c @@ -34,9 +34,12 @@ static enum drm_connector_status mdp4_lvds_connector_detect( struct mdp4_lvds_connector *mdp4_lvds_connector = to_mdp4_lvds_connector(connector); - if (!mdp4_lvds_connector->panel) + if (!mdp4_lvds_connector->panel) { mdp4_lvds_connector->panel = of_drm_find_panel(mdp4_lvds_connector->panel_node); + if (IS_ERR(mdp4_lvds_connector->panel)) + mdp4_lvds_connector->panel = NULL; + } return mdp4_lvds_connector->panel ? connector_status_connected : diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 2f1a2780658a..29841f440111 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1898,7 +1898,7 @@ int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer) * output */ if (check_defer && msm_host->device_node) { - if (!of_drm_find_panel(msm_host->device_node)) + if (IS_ERR(of_drm_find_panel(msm_host->device_node))) if (!of_drm_find_bridge(msm_host->device_node)) return -EPROBE_DEFER; } diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 155ad840f3c5..5d8e391e75f4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -434,8 +434,8 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) ret = -EPROBE_DEFER; } else { lvds->panel = of_drm_find_panel(remote); - if (!lvds->panel) - ret = -EPROBE_DEFER; + if (IS_ERR(lvds->panel)) + ret = PTR_ERR(lvds->panel); } done: diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index d53d5a09547f..01642aaf6127 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c @@ -595,7 +595,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, dsi->format = device->format; dsi->mode_flags = device->mode_flags; dsi->panel = of_drm_find_panel(device->dev.of_node); - if (dsi->panel) + if (!IS_ERR(dsi->panel)) return drm_panel_attach(dsi->panel, &dsi->connector); return -EINVAL; diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c index a5979cd25cc7..030da55a8d30 100644 --- a/drivers/gpu/drm/sti/sti_dvo.c +++ b/drivers/gpu/drm/sti/sti_dvo.c @@ -387,7 +387,9 @@ sti_dvo_connector_detect(struct drm_connector *connector, bool force) if (!dvo->panel) { dvo->panel = of_drm_find_panel(dvo->panel_node); - if (dvo->panel) + if (IS_ERR(dvo->panel)) + dvo->panel = NULL; + else drm_panel_attach(dvo->panel, connector); } diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index da9814f94d00..2b40d1f6aee8 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -833,8 +833,8 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host, dsi->device = device; dsi->panel = of_drm_find_panel(device->dev.of_node); - if (!dsi->panel) - return -EINVAL; + if (IS_ERR(dsi->panel)) + return PTR_ERR(dsi->panel); dev_info(host->dev, "Attached device %s\n", device->name); diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 87c5d89bc9ba..ad88ec230329 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -1411,6 +1411,9 @@ static int tegra_dsi_host_attach(struct mipi_dsi_host *host, struct tegra_output *output = &dsi->output; output->panel = of_drm_find_panel(device->dev.of_node); + if (IS_ERR(output->panel)) + output->panel = NULL; + if (output->panel && output->connector.dev) { drm_panel_attach(output->panel, &output->connector); drm_helper_hpd_irq_event(output->connector.dev); diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index ffe34bd0bb9d..0c0936511bb4 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -110,8 +110,8 @@ int tegra_output_probe(struct tegra_output *output) panel = of_parse_phandle(output->of_node, "nvidia,panel", 0); if (panel) { output->panel = of_drm_find_panel(panel); - if (!output->panel) - return -EPROBE_DEFER; + if (IS_ERR(output->panel)) + return PTR_ERR(output->panel); of_node_put(panel); } diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 26a1b5fd8796..582a0ec0aa70 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -200,7 +200,7 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np); #else static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) { - return NULL; + return ERR_PTR(-ENODEV); } #endif -- cgit From 2e64a174179a144742fa70f09803a012aceca476 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 9 May 2018 15:00:41 +0200 Subject: drm/of: Make drm_of_find_panel_or_bridge() fail when the device is disabled There's no point searching for a drm_bridge or drm_panel if the OF node we're pointing has a status property that is not "okay" or "ok". Just return -ENODEV in this case. Signed-off-by: Boris Brezillon Reviewed-by: Thierry Reding Acked-by: Thierry Reding Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180509130042.9435-4-boris.brezillon@bootlin.com --- drivers/gpu/drm/drm_of.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/drm_of.c') diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 1f4a16772583..260612958cbe 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -239,6 +239,11 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, if (!remote) return -ENODEV; + if (!of_device_is_available(remote)) { + of_node_put(remote); + return -ENODEV; + } + if (panel) { *panel = of_drm_find_panel(remote); if (!IS_ERR(*panel)) -- cgit From 7f9e7ec92be93e73ef552e6185a3ada72a90e1a9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 9 Jul 2018 10:40:14 +0200 Subject: drm/doc: Include drm_of.c helpers Fixes a dead link I spotted in the struct drm_crtc docs. Comments themselves are in a surprisingly good state. v2: Fix subject typo (Sean). Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180709084016.23750-14-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms-helpers.rst | 9 +++++++++ drivers/gpu/drm/drm_of.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_of.c') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index a0a75342d732..f9cfcdcdf024 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -300,6 +300,15 @@ Auxiliary Modeset Helpers .. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c :export: +OF/DT Helpers +============= + +.. kernel-doc:: drivers/gpu/drm/drm_of.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_of.c + :export: + Legacy Plane Helper Reference ============================= diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 260612958cbe..2763a5ec845b 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -9,6 +9,13 @@ #include #include +/** + * DOC: overview + * + * A set of helper functions to aid DRM drivers in parsing standard DT + * properties. + */ + static void drm_release_of(struct device *dev, void *data) { of_node_put(data); @@ -94,7 +101,7 @@ EXPORT_SYMBOL_GPL(drm_of_component_match_add); * drm_of_component_probe - Generic probe function for a component based master * @dev: master device containing the OF node * @compare_of: compare function used for matching components - * @master_ops: component master ops to be used + * @m_ops: component master ops to be used * * Parse the platform device OF node and bind all the components associated * with the master. Interface ports are added before the encoders in order to -- cgit