Commit 9380dc33 authored by Ludovic Desroches's avatar Ludovic Desroches Committed by Neil Armstrong
Browse files

drm/panel: simple: restore connector_type fallback



The switch from devm_kzalloc() + drm_panel_init() to
devm_drm_panel_alloc() introduced a regression.

Several panel descriptors do not set connector_type. For those panels,
panel_simple_probe() used to compute a connector type (currently DPI as a
fallback) and pass that value to drm_panel_init(). After the conversion
to devm_drm_panel_alloc(), the call unconditionally used
desc->connector_type instead, ignoring the computed fallback and
potentially passing DRM_MODE_CONNECTOR_Unknown, which
drm_panel_bridge_add() does not allow.

Move the connector_type validation / fallback logic before the
devm_drm_panel_alloc() call and pass the computed connector_type to
devm_drm_panel_alloc(), so panels without an explicit connector_type
once again get the DPI default.

Signed-off-by: default avatarLudovic Desroches <ludovic.desroches@microchip.com>
Fixes: de04bb00 ("drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()")
Cc: stable@vger.kernel.org
Reviewed-by: default avatarLuca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://lore.kernel.org/stable/20251126-lcd_panel_connector_type_fix-v2-1-c15835d1f7cb%40microchip.com


Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20251218-lcd_panel_connector_type_fix-v3-1-ddcea6d8d7ef@microchip.com
parent 6ab3d435
Loading
Loading
Loading
Loading
+44 −45
Original line number Diff line number Diff line
@@ -623,49 +623,6 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
	if (IS_ERR(desc))
		return ERR_CAST(desc);

	panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
				     &panel_simple_funcs, desc->connector_type);
	if (IS_ERR(panel))
		return ERR_CAST(panel);

	panel->desc = desc;

	panel->supply = devm_regulator_get(dev, "power");
	if (IS_ERR(panel->supply))
		return ERR_CAST(panel->supply);

	panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
						     GPIOD_OUT_LOW);
	if (IS_ERR(panel->enable_gpio))
		return dev_err_cast_probe(dev, panel->enable_gpio,
					  "failed to request GPIO\n");

	err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
	if (err) {
		dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
		return ERR_PTR(err);
	}

	ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
	if (ddc) {
		panel->ddc = of_find_i2c_adapter_by_node(ddc);
		of_node_put(ddc);

		if (!panel->ddc)
			return ERR_PTR(-EPROBE_DEFER);
	}

	if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
	    !of_get_display_timing(dev->of_node, "panel-timing", &dt))
		panel_simple_parse_panel_timing_node(dev, panel, &dt);

	if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
		/* Optional data-mapping property for overriding bus format */
		err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
		if (err)
			goto free_ddc;
	}

	connector_type = desc->connector_type;
	/* Catch common mistakes for panels. */
	switch (connector_type) {
@@ -690,8 +647,7 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
		break;
	case DRM_MODE_CONNECTOR_eDP:
		dev_warn(dev, "eDP panels moved to panel-edp\n");
		err = -EINVAL;
		goto free_ddc;
		return ERR_PTR(-EINVAL);
	case DRM_MODE_CONNECTOR_DSI:
		if (desc->bpc != 6 && desc->bpc != 8)
			dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
@@ -720,6 +676,49 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
		break;
	}

	panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
				     &panel_simple_funcs, connector_type);
	if (IS_ERR(panel))
		return ERR_CAST(panel);

	panel->desc = desc;

	panel->supply = devm_regulator_get(dev, "power");
	if (IS_ERR(panel->supply))
		return ERR_CAST(panel->supply);

	panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
						     GPIOD_OUT_LOW);
	if (IS_ERR(panel->enable_gpio))
		return dev_err_cast_probe(dev, panel->enable_gpio,
					  "failed to request GPIO\n");

	err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
	if (err) {
		dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
		return ERR_PTR(err);
	}

	ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
	if (ddc) {
		panel->ddc = of_find_i2c_adapter_by_node(ddc);
		of_node_put(ddc);

		if (!panel->ddc)
			return ERR_PTR(-EPROBE_DEFER);
	}

	if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
	    !of_get_display_timing(dev->of_node, "panel-timing", &dt))
		panel_simple_parse_panel_timing_node(dev, panel, &dt);

	if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
		/* Optional data-mapping property for overriding bus format */
		err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
		if (err)
			goto free_ddc;
	}

	dev_set_drvdata(dev, panel);

	/*