@@ -263,6 +263,9 @@ static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
if (bridge->funcs->debugfs_init)
bridge->funcs->debugfs_init(bridge, root);
}
+
+ if (bridge_connector->bridge_hdmi)
+ drm_hdmi_connector_debugfs_init(connector, root);
}
static struct drm_connector_state *
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT
+#include <linux/debugfs.h>
#include <linux/export.h>
#include <drm/drm_atomic.h>
@@ -965,6 +966,159 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_hdmi_connector_mode_valid);
+static ssize_t
+audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
+{
+ struct drm_connector_hdmi_infoframe *infoframe;
+ struct drm_connector *connector;
+ union hdmi_infoframe *frame;
+ u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+ ssize_t len = 0;
+
+ connector = filp->private_data;
+ mutex_lock(&connector->hdmi.infoframes.lock);
+
+ infoframe = &connector->hdmi.infoframes.audio;
+ if (!infoframe->set)
+ goto out;
+
+ frame = &infoframe->data;
+ len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+ if (len < 0)
+ goto out;
+
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+
+out:
+ mutex_unlock(&connector->hdmi.infoframes.lock);
+ return len;
+}
+
+static const struct file_operations audio_infoframe_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = audio_infoframe_read,
+};
+
+static int create_hdmi_audio_infoframe_file(struct drm_connector *connector,
+ struct dentry *parent)
+{
+ struct dentry *file;
+
+ if (!connector->hdmi.funcs ||
+ !connector->hdmi.funcs->audio.write_infoframe)
+ return 0;
+
+ file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ return 0;
+}
+
+#define DEFINE_INFOFRAME_FILE(_f) \
+static ssize_t _f##_read_infoframe(struct file *filp, \
+ char __user *ubuf, \
+ size_t count, \
+ loff_t *ppos) \
+{ \
+ struct drm_connector_hdmi_infoframe *infoframe; \
+ struct drm_connector_state *conn_state; \
+ struct drm_connector *connector; \
+ union hdmi_infoframe *frame; \
+ struct drm_device *dev; \
+ u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \
+ ssize_t len = 0; \
+ \
+ connector = filp->private_data; \
+ dev = connector->dev; \
+ \
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); \
+ \
+ conn_state = connector->state; \
+ infoframe = &conn_state->hdmi.infoframes._f; \
+ if (!infoframe->set) \
+ goto out; \
+ \
+ frame = &infoframe->data; \
+ len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); \
+ if (len < 0) \
+ goto out; \
+ \
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len); \
+ \
+out: \
+ drm_modeset_unlock(&dev->mode_config.connection_mutex); \
+ return len; \
+} \
+\
+static const struct file_operations _f##_infoframe_fops = { \
+ .owner = THIS_MODULE, \
+ .open = simple_open, \
+ .read = _f##_read_infoframe, \
+}; \
+\
+static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, \
+ struct dentry *parent) \
+{ \
+ struct dentry *file; \
+ \
+ if (!connector->hdmi.funcs || \
+ !connector->hdmi.funcs->_f.write_infoframe) \
+ return 0; \
+ file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \
+ if (IS_ERR(file)) \
+ return PTR_ERR(file); \
+ \
+ return 0; \
+}
+
+DEFINE_INFOFRAME_FILE(avi);
+DEFINE_INFOFRAME_FILE(hdmi);
+DEFINE_INFOFRAME_FILE(hdr_drm);
+DEFINE_INFOFRAME_FILE(spd);
+
+static int create_hdmi_infoframe_files(struct drm_connector *connector,
+ struct dentry *parent)
+{
+ int ret;
+
+ ret = create_hdmi_audio_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_avi_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_hdmi_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_hdr_drm_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_spd_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void drm_hdmi_connector_debugfs_init(struct drm_connector *connector,
+ struct dentry *root)
+{
+ struct dentry *dir;
+
+ dir = debugfs_create_dir("infoframes", root);
+ if (IS_ERR(dir))
+ return;
+
+ create_hdmi_infoframe_files(connector, dir);
+}
+EXPORT_SYMBOL(drm_hdmi_connector_debugfs_init);
+
static int clear_infoframe(struct drm_connector *connector,
const struct drm_connector_infoframe_funcs *funcs,
const char *type)
@@ -633,161 +633,6 @@ static const struct file_operations drm_connector_fops = {
.write = connector_write
};
-static ssize_t
-audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
-{
- struct drm_connector_hdmi_infoframe *infoframe;
- struct drm_connector *connector;
- union hdmi_infoframe *frame;
- u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
- ssize_t len = 0;
-
- connector = filp->private_data;
- mutex_lock(&connector->hdmi.infoframes.lock);
-
- infoframe = &connector->hdmi.infoframes.audio;
- if (!infoframe->set)
- goto out;
-
- frame = &infoframe->data;
- len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
- if (len < 0)
- goto out;
-
- len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
-
-out:
- mutex_unlock(&connector->hdmi.infoframes.lock);
- return len;
-}
-
-static const struct file_operations audio_infoframe_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = audio_infoframe_read,
-};
-
-static int create_hdmi_audio_infoframe_file(struct drm_connector *connector,
- struct dentry *parent)
-{
- struct dentry *file;
-
- if (!connector->hdmi.funcs ||
- !connector->hdmi.funcs->audio.write_infoframe)
- return 0;
-
- file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops);
- if (IS_ERR(file))
- return PTR_ERR(file);
-
- return 0;
-}
-
-#define DEFINE_INFOFRAME_FILE(_f) \
-static ssize_t _f##_read_infoframe(struct file *filp, \
- char __user *ubuf, \
- size_t count, \
- loff_t *ppos) \
-{ \
- struct drm_connector_hdmi_infoframe *infoframe; \
- struct drm_connector_state *conn_state; \
- struct drm_connector *connector; \
- union hdmi_infoframe *frame; \
- struct drm_device *dev; \
- u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \
- ssize_t len = 0; \
- \
- connector = filp->private_data; \
- dev = connector->dev; \
- \
- drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); \
- \
- conn_state = connector->state; \
- infoframe = &conn_state->hdmi.infoframes._f; \
- if (!infoframe->set) \
- goto out; \
- \
- frame = &infoframe->data; \
- len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); \
- if (len < 0) \
- goto out; \
- \
- len = simple_read_from_buffer(ubuf, count, ppos, buf, len); \
- \
-out: \
- drm_modeset_unlock(&dev->mode_config.connection_mutex); \
- return len; \
-} \
-\
-static const struct file_operations _f##_infoframe_fops = { \
- .owner = THIS_MODULE, \
- .open = simple_open, \
- .read = _f##_read_infoframe, \
-}; \
-\
-static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, \
- struct dentry *parent) \
-{ \
- struct dentry *file; \
- \
- if (!connector->hdmi.funcs || \
- !connector->hdmi.funcs->_f.write_infoframe) \
- return 0; \
- file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \
- if (IS_ERR(file)) \
- return PTR_ERR(file); \
- \
- return 0; \
-}
-
-DEFINE_INFOFRAME_FILE(avi);
-DEFINE_INFOFRAME_FILE(hdmi);
-DEFINE_INFOFRAME_FILE(hdr_drm);
-DEFINE_INFOFRAME_FILE(spd);
-
-static int create_hdmi_infoframe_files(struct drm_connector *connector,
- struct dentry *parent)
-{
- int ret;
-
- ret = create_hdmi_audio_infoframe_file(connector, parent);
- if (ret)
- return ret;
-
- ret = create_hdmi_avi_infoframe_file(connector, parent);
- if (ret)
- return ret;
-
- ret = create_hdmi_hdmi_infoframe_file(connector, parent);
- if (ret)
- return ret;
-
- ret = create_hdmi_hdr_drm_infoframe_file(connector, parent);
- if (ret)
- return ret;
-
- ret = create_hdmi_spd_infoframe_file(connector, parent);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static void hdmi_debugfs_add(struct drm_connector *connector)
-{
- struct dentry *dir;
-
- if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
- connector->connector_type == DRM_MODE_CONNECTOR_HDMIB))
- return;
-
- dir = debugfs_create_dir("infoframes", connector->debugfs_entry);
- if (IS_ERR(dir))
- return;
-
- create_hdmi_infoframe_files(connector, dir);
-}
-
void drm_debugfs_connector_add(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -815,8 +660,6 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
debugfs_create_file("output_bpc", 0444, root, connector,
&output_bpc_fops);
- hdmi_debugfs_add(connector);
-
if (connector->funcs->debugfs_init)
connector->funcs->debugfs_init(connector, root);
}
@@ -292,6 +292,7 @@ static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
}
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
+ .debugfs_init = drm_hdmi_connector_debugfs_init,
.detect = sun4i_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = sun4i_hdmi_connector_reset,
@@ -513,6 +513,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector)
}
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+ .debugfs_init = drm_hdmi_connector_debugfs_init,
.force = drm_atomic_helper_connector_hdmi_force,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = vc4_hdmi_connector_reset,
@@ -3,6 +3,7 @@
#ifndef DRM_HDMI_STATE_HELPER_H_
#define DRM_HDMI_STATE_HELPER_H_
+struct dentry;
struct drm_atomic_commit;
struct drm_connector;
struct drm_connector_state;
@@ -29,5 +30,7 @@ void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
enum drm_mode_status
drm_hdmi_connector_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode);
+void drm_hdmi_connector_debugfs_init(struct drm_connector *connector,
+ struct dentry *root);
#endif // DRM_HDMI_STATE_HELPER_H_