summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2025-06-10 12:41:32 +0300
committerJani Nikula <jani.nikula@intel.com>2025-06-11 11:16:02 +0300
commit946540a02e903e3b749f535c86d59ac4640faa20 (patch)
treee85d551c7fedbd6624ae45311467730df2162f9b
parentedcc9d24fb8ece4e704f352f53733ea44986732b (diff)
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 <heikki.krogerus@linux.intel.com> Cc: Neil Armstrong <neil.armstrong@linaro.org> Cc: Jessica Zhang <jessica.zhang@oss.qualcomm.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Doug Anderson <dianders@chromium.org> Cc: Lee Shawn C <shawn.c.lee@intel.com> Tested-by: Lee Shawn C <shawn.c.lee@intel.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Tested-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Arun R Murthy <arun.r.murthy@intel.com> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://lore.kernel.org/r/20250610094132.3240567-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/drm_panel.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index fee65dc65979..805b4151ccef 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);