From: Jani Nikula Date: Tue, 10 Jun 2025 09:41:32 +0000 (+0300) Subject: drm/panel: use fwnode based lookups for panel followers X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=946540a02e903e3b749f535c86d59ac4640faa20;p=thirdparty%2Flinux.git drm/panel: use fwnode based lookups for panel followers Use firmware node based lookups for panel followers, to make the code independent of OF and device tree, and make it work also for ACPI with an appropriate _DSD. ASL example: Package (0x02) { "panel", \_SB.PCI0.GFX0.LCD0 } v2: - Update comments (Doug, Arun) - s/IS_ERR_OR_NULL/IS_ERR/ (Doug) Suggested-by: Heikki Krogerus Cc: Neil Armstrong Cc: Jessica Zhang Cc: Maxime Ripard Cc: Doug Anderson Cc: Lee Shawn C Tested-by: Lee Shawn C Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Reviewed-by: Arun R Murthy Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20250610094132.3240567-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index fee65dc65979d..805b4151ccefd 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c @@ -473,17 +473,40 @@ int of_drm_get_panel_orientation(const struct device_node *np, EXPORT_SYMBOL(of_drm_get_panel_orientation); #endif -static struct drm_panel *of_find_panel(struct device *follower_dev) +/* Find panel by fwnode. This should be identical to of_drm_find_panel(). */ +static struct drm_panel *find_panel_by_fwnode(const struct fwnode_handle *fwnode) { - struct device_node *panel_np; struct drm_panel *panel; - panel_np = of_parse_phandle(follower_dev->of_node, "panel", 0); - if (!panel_np) + if (!fwnode_device_is_available(fwnode)) return ERR_PTR(-ENODEV); - panel = of_drm_find_panel(panel_np); - of_node_put(panel_np); + mutex_lock(&panel_lock); + + list_for_each_entry(panel, &panel_list, list) { + if (dev_fwnode(panel->dev) == fwnode) { + mutex_unlock(&panel_lock); + return panel; + } + } + + mutex_unlock(&panel_lock); + + return ERR_PTR(-EPROBE_DEFER); +} + +/* Find panel by follower device */ +static struct drm_panel *find_panel_by_dev(struct device *follower_dev) +{ + struct fwnode_handle *fwnode; + struct drm_panel *panel; + + fwnode = fwnode_find_reference(dev_fwnode(follower_dev), "panel", 0); + if (IS_ERR(fwnode)) + return ERR_PTR(-ENODEV); + + panel = find_panel_by_fwnode(fwnode); + fwnode_handle_put(fwnode); return panel; } @@ -494,7 +517,7 @@ static struct drm_panel *of_find_panel(struct device *follower_dev) * * This checks to see if a device needs to be power sequenced together with * a panel using the panel follower API. - * At the moment panels can only be followed on device tree enabled systems. + * * The "panel" property of the follower points to the panel to be followed. * * Return: true if we should be power sequenced with a panel; false otherwise. @@ -506,7 +529,7 @@ bool drm_is_panel_follower(struct device *dev) * don't bother trying to parse it here. We just need to know if the * property is there. */ - return of_property_present(dev->of_node, "panel"); + return device_property_present(dev, "panel"); } EXPORT_SYMBOL(drm_is_panel_follower); @@ -523,7 +546,6 @@ EXPORT_SYMBOL(drm_is_panel_follower); * If a follower is added to a panel that's already been turned on, the * follower's prepare callback is called right away. * - * At the moment panels can only be followed on device tree enabled systems. * The "panel" property of the follower points to the panel to be followed. * * Return: 0 or an error code. Note that -ENODEV means that we detected that @@ -536,7 +558,7 @@ int drm_panel_add_follower(struct device *follower_dev, struct drm_panel *panel; int ret; - panel = of_find_panel(follower_dev); + panel = find_panel_by_dev(follower_dev); if (IS_ERR(panel)) return PTR_ERR(panel);