drm: Plumb debugfs_init through to panels
authorDouglas Anderson <dianders@chromium.org>
Sat, 5 Feb 2022 00:13:41 +0000 (16:13 -0800)
committerDouglas Anderson <dianders@chromium.org>
Tue, 15 Feb 2022 23:25:18 +0000 (15:25 -0800)
We'd like panels to be able to add things to debugfs underneath the
connector's directory. Let's plumb it through. A panel will be able to
put things in a "panel" directory under the connector's
directory. Note that debugfs is not ABI and so it's always possible
that the location that the panel gets for its debugfs could change in
the future.

NOTE: this currently only works if you're using a modern
architecture. Specifically the plumbing relies on _both_
drm_bridge_connector and drm_panel_bridge. If you're not using one or
both of these things then things won't be plumbed through.

As a side effect of this change, drm_bridges can also get callbacks to
put stuff underneath the connector's debugfs directory. At the moment
all bridges in the chain have their debugfs_init() called with the
connector's root directory.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220204161245.v2.2.Ib0bd5346135cbb0b63006b69b61d4c8af6484740@changeid
drivers/gpu/drm/bridge/panel.c
drivers/gpu/drm/drm_bridge_connector.c
drivers/gpu/drm/drm_debugfs.c
include/drm/drm_bridge.h
include/drm/drm_connector.h
include/drm/drm_panel.h

index b32295abd9e7506c36c014629fb17a1b16f466e1..5be0575751831a04f70f12095d57e65535acc122 100644 (file)
@@ -138,6 +138,17 @@ static int panel_bridge_get_modes(struct drm_bridge *bridge,
        return drm_panel_get_modes(panel_bridge->panel, connector);
 }
 
+static void panel_bridge_debugfs_init(struct drm_bridge *bridge,
+                                     struct dentry *root)
+{
+       struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+       struct drm_panel *panel = panel_bridge->panel;
+
+       root = debugfs_create_dir("panel", root);
+       if (panel->funcs->debugfs_init)
+               panel->funcs->debugfs_init(panel, root);
+}
+
 static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
        .attach = panel_bridge_attach,
        .detach = panel_bridge_detach,
@@ -150,6 +161,7 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
        .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
        .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
+       .debugfs_init = panel_bridge_debugfs_init,
 };
 
 /**
index 791379816837d8bfe0a2f46811d59c016964df7f..60923cdfe8e1c41152e78a205cebcb8275300b1b 100644 (file)
@@ -216,6 +216,20 @@ static void drm_bridge_connector_destroy(struct drm_connector *connector)
        kfree(bridge_connector);
 }
 
+static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
+                                             struct dentry *root)
+{
+       struct drm_bridge_connector *bridge_connector =
+               to_drm_bridge_connector(connector);
+       struct drm_encoder *encoder = bridge_connector->encoder;
+       struct drm_bridge *bridge;
+
+       list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) {
+               if (bridge->funcs->debugfs_init)
+                       bridge->funcs->debugfs_init(bridge, root);
+       }
+}
+
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
        .reset = drm_atomic_helper_connector_reset,
        .detect = drm_bridge_connector_detect,
@@ -223,6 +237,7 @@ static const struct drm_connector_funcs drm_bridge_connector_funcs = {
        .destroy = drm_bridge_connector_destroy,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+       .debugfs_init = drm_bridge_connector_debugfs_init,
 };
 
 /* -----------------------------------------------------------------------------
index b0a826489488596e8b66bd3271bae4a66fe2f996..7f1b82dbaebb90dbfdc91c47a0fb0b9932a994e4 100644 (file)
@@ -436,6 +436,9 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
        /* vrr range */
        debugfs_create_file("vrr_range", S_IRUGO, root, connector,
                            &vrr_range_fops);
+
+       if (connector->funcs->debugfs_init)
+               connector->funcs->debugfs_init(connector, root);
 }
 
 void drm_debugfs_connector_remove(struct drm_connector *connector)
index 061d87313fac9a1cac45fd85d2313517e64c2b2f..f27b4060faa2f68c7430d9470a75427e499c0249 100644 (file)
@@ -649,6 +649,13 @@ struct drm_bridge_funcs {
         * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops.
         */
        void (*hpd_disable)(struct drm_bridge *bridge);
+
+       /**
+        * @debugfs_init:
+        *
+        * Allows bridges to create bridge-specific debugfs files.
+        */
+       void (*debugfs_init)(struct drm_bridge *bridge, struct dentry *root);
 };
 
 /**
index 5e36eb3df66f209a509f1bc3a52c4059f902cb07..5166186146f432a236173af8b5caf4361e4e87e7 100644 (file)
@@ -1142,6 +1142,13 @@ struct drm_connector_funcs {
         * has been received from a source outside the display driver / device.
         */
        void (*oob_hotplug_event)(struct drm_connector *connector);
+
+       /**
+        * @debugfs_init:
+        *
+        * Allows connectors to create connector-specific debugfs files.
+        */
+       void (*debugfs_init)(struct drm_connector *connector, struct dentry *root);
 };
 
 /**
index 4602f833eb51d5d9f189df62f0dd68021ed46c4a..1ba2d424a53ff54e2401283e88c3d24cdeafb0d5 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 
 struct backlight_device;
+struct dentry;
 struct device_node;
 struct drm_connector;
 struct drm_device;
@@ -125,6 +126,13 @@ struct drm_panel_funcs {
         */
        int (*get_timings)(struct drm_panel *panel, unsigned int num_timings,
                           struct display_timing *timings);
+
+       /**
+        * @debugfs_init:
+        *
+        * Allows panels to create panels-specific debugfs files.
+        */
+       void (*debugfs_init)(struct drm_panel *panel, struct dentry *root);
 };
 
 /**