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 <boris.brezillon@bootlin.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180509130042.9435-2-boris.brezillon@bootlin.com
This commit is contained in:
Boris Brezillon 2018-05-09 15:00:39 +02:00 committed by Thierry Reding
parent 0ca0c827ef
commit 5fa8e4a221
18 changed files with 43 additions and 25 deletions

View File

@ -1152,7 +1152,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host,
np = of_node_get(dev->dev.of_node); np = of_node_get(dev->dev.of_node);
panel = of_drm_find_panel(np); panel = of_drm_find_panel(np);
if (panel) { if (!IS_ERR(panel)) {
bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI); bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
} else { } else {
bridge = of_drm_find_bridge(dev->dev.of_node); bridge = of_drm_find_bridge(dev->dev.of_node);

View File

@ -68,9 +68,9 @@ static int lvds_encoder_probe(struct platform_device *pdev)
panel = of_drm_find_panel(panel_node); panel = of_drm_find_panel(panel_node);
of_node_put(panel_node); of_node_put(panel_node);
if (!panel) { if (IS_ERR(panel)) {
dev_dbg(&pdev->dev, "panel not found, deferring probe\n"); dev_dbg(&pdev->dev, "panel not found, deferring probe\n");
return -EPROBE_DEFER; return PTR_ERR(panel);
} }
lvds_encoder->panel_bridge = lvds_encoder->panel_bridge =

View File

@ -241,8 +241,10 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
if (panel) { if (panel) {
*panel = of_drm_find_panel(remote); *panel = of_drm_find_panel(remote);
if (*panel) if (!IS_ERR(*panel))
ret = 0; ret = 0;
else
*panel = NULL;
} }
/* No panel found yet, check for a bridge next. */ /* No panel found yet, check for a bridge next. */

View File

@ -151,7 +151,9 @@ EXPORT_SYMBOL(drm_panel_detach);
* tree node. If a matching panel is found, return a pointer to it. * 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 * 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) 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); mutex_unlock(&panel_lock);
return NULL; return ERR_PTR(-EPROBE_DEFER);
} }
EXPORT_SYMBOL(of_drm_find_panel); EXPORT_SYMBOL(of_drm_find_panel);
#endif #endif

View File

@ -232,9 +232,11 @@ static int exynos_dp_probe(struct platform_device *pdev)
np = of_parse_phandle(dev->of_node, "panel", 0); np = of_parse_phandle(dev->of_node, "panel", 0);
if (np) { if (np) {
dp->plat_data.panel = of_drm_find_panel(np); dp->plat_data.panel = of_drm_find_panel(np);
of_node_put(np); of_node_put(np);
if (!dp->plat_data.panel) if (IS_ERR(dp->plat_data.panel))
return -EPROBE_DEFER; return PTR_ERR(dp->plat_data.panel);
goto out; goto out;
} }

View File

@ -240,8 +240,8 @@ struct drm_encoder *exynos_dpi_probe(struct device *dev)
if (ctx->panel_node) { if (ctx->panel_node) {
ctx->panel = of_drm_find_panel(ctx->panel_node); ctx->panel = of_drm_find_panel(ctx->panel_node);
if (!ctx->panel) if (IS_ERR(ctx->panel))
return ERR_PTR(-EPROBE_DEFER); return ERR_CAST(ctx->panel);
} }
return &ctx->encoder; return &ctx->encoder;

View File

@ -1519,6 +1519,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
dsi->format = device->format; dsi->format = device->format;
dsi->mode_flags = device->mode_flags; dsi->mode_flags = device->mode_flags;
dsi->panel = of_drm_find_panel(device->dev.of_node); dsi->panel = of_drm_find_panel(device->dev.of_node);
if (IS_ERR(dsi->panel))
dsi->panel = NULL;
if (dsi->panel) { if (dsi->panel) {
drm_panel_attach(dsi->panel, &dsi->connector); drm_panel_attach(dsi->panel, &dsi->connector);
dsi->connector.status = connector_status_connected; dsi->connector.status = connector_status_connected;

View File

@ -148,8 +148,9 @@ int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev)
if (panel_node) { if (panel_node) {
fsl_dev->connector.panel = of_drm_find_panel(panel_node); fsl_dev->connector.panel = of_drm_find_panel(panel_node);
of_node_put(panel_node); of_node_put(panel_node);
if (!fsl_dev->connector.panel) if (IS_ERR(fsl_dev->connector.panel))
return -EPROBE_DEFER; return PTR_ERR(fsl_dev->connector.panel);
return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel); return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
} }

View File

@ -341,7 +341,7 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
if (panel) { if (!IS_ERR(panel)) {
drm_panel_disable(panel); drm_panel_disable(panel);
drm_panel_unprepare(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); dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
if (panel) { if (!IS_ERR(panel)) {
drm_panel_prepare(panel); drm_panel_prepare(panel);
drm_panel_enable(panel); drm_panel_enable(panel);
} }

View File

@ -34,9 +34,12 @@ static enum drm_connector_status mdp4_lvds_connector_detect(
struct mdp4_lvds_connector *mdp4_lvds_connector = struct mdp4_lvds_connector *mdp4_lvds_connector =
to_mdp4_lvds_connector(connector); to_mdp4_lvds_connector(connector);
if (!mdp4_lvds_connector->panel) if (!mdp4_lvds_connector->panel) {
mdp4_lvds_connector->panel = mdp4_lvds_connector->panel =
of_drm_find_panel(mdp4_lvds_connector->panel_node); 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 ? return mdp4_lvds_connector->panel ?
connector_status_connected : connector_status_connected :

View File

@ -1898,7 +1898,7 @@ int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer)
* output * output
*/ */
if (check_defer && msm_host->device_node) { 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)) if (!of_drm_find_bridge(msm_host->device_node))
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }

View File

@ -434,8 +434,8 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
ret = -EPROBE_DEFER; ret = -EPROBE_DEFER;
} else { } else {
lvds->panel = of_drm_find_panel(remote); lvds->panel = of_drm_find_panel(remote);
if (!lvds->panel) if (IS_ERR(lvds->panel))
ret = -EPROBE_DEFER; ret = PTR_ERR(lvds->panel);
} }
done: done:

View File

@ -595,7 +595,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
dsi->format = device->format; dsi->format = device->format;
dsi->mode_flags = device->mode_flags; dsi->mode_flags = device->mode_flags;
dsi->panel = of_drm_find_panel(device->dev.of_node); 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 drm_panel_attach(dsi->panel, &dsi->connector);
return -EINVAL; return -EINVAL;

View File

@ -387,7 +387,9 @@ sti_dvo_connector_detect(struct drm_connector *connector, bool force)
if (!dvo->panel) { if (!dvo->panel) {
dvo->panel = of_drm_find_panel(dvo->panel_node); 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); drm_panel_attach(dvo->panel, connector);
} }

View File

@ -833,8 +833,8 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
dsi->device = device; dsi->device = device;
dsi->panel = of_drm_find_panel(device->dev.of_node); dsi->panel = of_drm_find_panel(device->dev.of_node);
if (!dsi->panel) if (IS_ERR(dsi->panel))
return -EINVAL; return PTR_ERR(dsi->panel);
dev_info(host->dev, "Attached device %s\n", device->name); dev_info(host->dev, "Attached device %s\n", device->name);

View File

@ -1411,6 +1411,9 @@ static int tegra_dsi_host_attach(struct mipi_dsi_host *host,
struct tegra_output *output = &dsi->output; struct tegra_output *output = &dsi->output;
output->panel = of_drm_find_panel(device->dev.of_node); output->panel = of_drm_find_panel(device->dev.of_node);
if (IS_ERR(output->panel))
output->panel = NULL;
if (output->panel && output->connector.dev) { if (output->panel && output->connector.dev) {
drm_panel_attach(output->panel, &output->connector); drm_panel_attach(output->panel, &output->connector);
drm_helper_hpd_irq_event(output->connector.dev); drm_helper_hpd_irq_event(output->connector.dev);

View File

@ -110,8 +110,8 @@ int tegra_output_probe(struct tegra_output *output)
panel = of_parse_phandle(output->of_node, "nvidia,panel", 0); panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
if (panel) { if (panel) {
output->panel = of_drm_find_panel(panel); output->panel = of_drm_find_panel(panel);
if (!output->panel) if (IS_ERR(output->panel))
return -EPROBE_DEFER; return PTR_ERR(output->panel);
of_node_put(panel); of_node_put(panel);
} }

View File

@ -200,7 +200,7 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np);
#else #else
static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
{ {
return NULL; return ERR_PTR(-ENODEV);
} }
#endif #endif