]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/panel: simple: restore connector_type fallback
authorLudovic Desroches <ludovic.desroches@microchip.com>
Thu, 18 Dec 2025 13:34:43 +0000 (14:34 +0100)
committerNeil Armstrong <neil.armstrong@linaro.org>
Tue, 13 Jan 2026 09:07:40 +0000 (10:07 +0100)
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: Ludovic Desroches <ludovic.desroches@microchip.com>
Fixes: de04bb0089a9 ("drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()")
Cc: stable@vger.kernel.org
Reviewed-by: Luca 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: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20251218-lcd_panel_connector_type_fix-v3-1-ddcea6d8d7ef@microchip.com
drivers/gpu/drm/panel/panel-simple.c

index 246d6883fbf7f083b28f0a15829a839280b704bd..162cc58c7b8f037996866f77a79ab06832c5f509 100644 (file)
@@ -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);
 
        /*