Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panel: panel-simple: Add function to look panel data up

Commit de04bb0089a9 ("drm/panel/panel-simple: Use the new allocation in
place of devm_kzalloc()") moved the call to drm_panel_init into the
devm_drm_panel_alloc(), which needs a connector type to initialize
properly.

In the panel-dpi compatible case, the passed panel_desc structure is an
empty one used as a discriminant, and the connector type it contains
isn't actually initialized.

It is initialized through a call to panel_dpi_probe() later in the
function, which used to be before the call to drm_panel_init() that got
merged into devm_drm_panel_alloc().

So, we do need a proper panel_desc pointer before the call to
devm_drm_panel_alloc() now. All cases associate their panel_desc with
the panel compatible and use of_device_get_match_data, except for the
panel-dpi compatible.

In that case, we're expected to call panel_dpi_probe, which will
allocate and initialize the panel_desc for us.

Let's create such a helper function that would be called first in the
driver and will lookup the desc by compatible, or allocate one if
relevant.

Reported-by: Francesco Dolcini <francesco@dolcini.it>
Closes: https://lore.kernel.org/all/20250612081834.GA248237@francesco-nb/
Fixes: de04bb0089a9 ("drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()")
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com> # Toradex Colibri iMX6
Link: https://lore.kernel.org/r/20250626-drm-panel-simple-fixes-v2-4-5afcaa608bdc@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>

+49 -33
+49 -33
drivers/gpu/drm/panel/panel-simple.c
··· 26 26 #include <linux/i2c.h> 27 27 #include <linux/media-bus-format.h> 28 28 #include <linux/module.h> 29 + #include <linux/of_device.h> 29 30 #include <linux/of_platform.h> 30 31 #include <linux/platform_device.h> 31 32 #include <linux/pm_runtime.h> ··· 135 134 136 135 /** @connector_type: LVDS, eDP, DSI, DPI, etc. */ 137 136 int connector_type; 137 + }; 138 + 139 + struct panel_desc_dsi { 140 + struct panel_desc desc; 141 + 142 + unsigned long flags; 143 + enum mipi_dsi_pixel_format format; 144 + unsigned int lanes; 138 145 }; 139 146 140 147 struct panel_simple { ··· 576 567 return 0; 577 568 } 578 569 579 - static struct panel_simple *panel_simple_probe(struct device *dev, const struct panel_desc *desc) 570 + static const struct panel_desc *panel_simple_get_desc(struct device *dev) 580 571 { 572 + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI) && 573 + dev_is_mipi_dsi(dev)) { 574 + const struct panel_desc_dsi *dsi_desc; 575 + 576 + dsi_desc = of_device_get_match_data(dev); 577 + if (!dsi_desc) 578 + return ERR_PTR(-ENODEV); 579 + 580 + return &dsi_desc->desc; 581 + } 582 + 583 + if (dev_is_platform(dev)) { 584 + const struct panel_desc *desc; 585 + 586 + desc = of_device_get_match_data(dev); 587 + if (!desc) 588 + return ERR_PTR(-ENODEV); 589 + 590 + if (desc == &panel_dpi) 591 + return panel_dpi_probe(dev); 592 + 593 + return desc; 594 + } 595 + 596 + return ERR_PTR(-ENODEV); 597 + } 598 + 599 + static struct panel_simple *panel_simple_probe(struct device *dev) 600 + { 601 + const struct panel_desc *desc; 581 602 struct panel_simple *panel; 582 603 struct display_timing dt; 583 604 struct device_node *ddc; 584 605 int connector_type; 585 606 u32 bus_flags; 586 607 int err; 608 + 609 + desc = panel_simple_get_desc(dev); 610 + if (IS_ERR(desc)) 611 + return ERR_CAST(desc); 587 612 588 613 panel = devm_drm_panel_alloc(dev, struct panel_simple, base, 589 614 &panel_simple_funcs, desc->connector_type); ··· 651 608 return ERR_PTR(-EPROBE_DEFER); 652 609 } 653 610 654 - if (desc == &panel_dpi) { 655 - /* Handle the generic panel-dpi binding */ 656 - desc = panel_dpi_probe(dev); 657 - if (IS_ERR(desc)) { 658 - err = PTR_ERR(desc); 659 - goto free_ddc; 660 - } 661 - 662 - panel->desc = desc; 663 - } else { 664 - if (!of_get_display_timing(dev->of_node, "panel-timing", &dt)) 665 - panel_simple_parse_panel_timing_node(dev, panel, &dt); 666 - } 611 + if ((desc != &panel_dpi) && 612 + !of_get_display_timing(dev->of_node, "panel-timing", &dt)) 613 + panel_simple_parse_panel_timing_node(dev, panel, &dt); 667 614 668 615 if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) { 669 616 /* Optional data-mapping property for overriding bus format */ ··· 5409 5376 5410 5377 static int panel_simple_platform_probe(struct platform_device *pdev) 5411 5378 { 5412 - const struct panel_desc *desc; 5413 5379 struct panel_simple *panel; 5414 5380 5415 - desc = of_device_get_match_data(&pdev->dev); 5416 - if (!desc) 5417 - return -ENODEV; 5418 - 5419 - panel = panel_simple_probe(&pdev->dev, desc); 5381 + panel = panel_simple_probe(&pdev->dev); 5420 5382 if (IS_ERR(panel)) 5421 5383 return PTR_ERR(panel); 5422 5384 ··· 5443 5415 .probe = panel_simple_platform_probe, 5444 5416 .remove = panel_simple_platform_remove, 5445 5417 .shutdown = panel_simple_platform_shutdown, 5446 - }; 5447 - 5448 - struct panel_desc_dsi { 5449 - struct panel_desc desc; 5450 - 5451 - unsigned long flags; 5452 - enum mipi_dsi_pixel_format format; 5453 - unsigned int lanes; 5454 5418 }; 5455 5419 5456 5420 static const struct drm_display_mode auo_b080uan01_mode = { ··· 5681 5661 struct panel_simple *panel; 5682 5662 int err; 5683 5663 5684 - desc = of_device_get_match_data(&dsi->dev); 5685 - if (!desc) 5686 - return -ENODEV; 5687 - 5688 - panel = panel_simple_probe(&dsi->dev, &desc->desc); 5664 + panel = panel_simple_probe(&dsi->dev); 5689 5665 if (IS_ERR(panel)) 5690 5666 return PTR_ERR(panel); 5691 5667