Message ID | 1401379063-15375-3-git-send-email-thomas.wood@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi On Thu, May 29, 2014 at 5:57 PM, Thomas Wood <thomas.wood@intel.com> wrote: > Add a file to debugfs for each connector to enable modification of the > "force" connector attribute. This allows connectors to be enabled or > disabled for testing and debugging purposes. > > Signed-off-by: Thomas Wood <thomas.wood@intel.com> > --- > drivers/gpu/drm/drm_crtc.c | 17 ++++++- > drivers/gpu/drm/drm_debugfs.c | 101 ++++++++++++++++++++++++++++++++++++++++++ > include/drm/drmP.h | 11 +++++ > include/drm/drm_crtc.h | 2 + > 4 files changed, 130 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 998663c..59a2784 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -841,6 +841,8 @@ int drm_connector_init(struct drm_device *dev, > drm_object_attach_property(&connector->base, > dev->mode_config.dpms_property, 0); > > + connector->debugfs_entry = NULL; > + > out_put: > if (ret) > drm_mode_object_put(dev, &connector->base); > @@ -891,7 +893,19 @@ EXPORT_SYMBOL(drm_connector_cleanup); > */ > int drm_connector_register(struct drm_connector *connector) > { > - return drm_sysfs_connector_add(connector); > + int ret; > + > + ret = drm_sysfs_connector_add(connector); > + if (ret != 0) nitpick: I've never seen "xy != 0" in DRM code, I think "if (ret)" or "if (ret < 0)" is what we usually use.. > + return ret; > + > + ret = drm_debugfs_connector_add(connector); > + if (ret != 0) { > + drm_sysfs_connector_remove(connector); > + return ret; > + } > + > + return 0; > } > EXPORT_SYMBOL(drm_connector_register); > > @@ -904,6 +918,7 @@ EXPORT_SYMBOL(drm_connector_register); > void drm_connector_unregister(struct drm_connector *connector) > { > drm_sysfs_connector_remove(connector); > + drm_debugfs_connector_remove(connector); > } > EXPORT_SYMBOL(drm_connector_unregister); > > diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c > index b4b51d4..b57b614 100644 > --- a/drivers/gpu/drm/drm_debugfs.c > +++ b/drivers/gpu/drm/drm_debugfs.c > @@ -237,5 +237,106 @@ int drm_debugfs_cleanup(struct drm_minor *minor) > return 0; > } > > +static int connector_show(struct seq_file *m, void *data) > +{ > + struct drm_connector *connector = m->private; > + const char *status; > + > + switch (connector->force) { > + case DRM_FORCE_ON: > + status = "on\n"; > + break; > + > + case DRM_FORCE_ON_DIGITAL: > + status = "digital\n"; > + break; > + > + case DRM_FORCE_OFF: > + status = "off\n"; > + break; > + > + case DRM_FORCE_UNSPECIFIED: > + status = "unspecified\n"; > + break; > + > + default: > + return 0; > + } > + > + seq_puts(m, status); > + > + return 0; > +} > + > +static int connector_open(struct inode *inode, struct file *file) > +{ > + struct drm_connector *dev = inode->i_private; > + > + return single_open(file, connector_show, dev); > +} > + > +static ssize_t connector_write(struct file *file, const char __user *ubuf, > + size_t len, loff_t *offp) > +{ > + struct seq_file *m = file->private_data; > + struct drm_connector *connector = m->private; > + > + if (strncmp(ubuf, "on", len) == 0) That hits on "o" as strncmp("o", "on", 1) == 0. We really need a "startswith()" macro in the kernel.. same below. > + connector->force = DRM_FORCE_ON; > + else if (strncmp(ubuf, "digital", len) == 0) > + connector->force = DRM_FORCE_ON_DIGITAL; > + else if (strncmp(ubuf, "off", len) == 0) > + connector->force = DRM_FORCE_OFF; > + else if (strncmp(ubuf, "unspecified", len) == 0) > + connector->force = DRM_FORCE_UNSPECIFIED; > + else > + return -EINVAL; > + > + return len; > +} > + > +static const struct file_operations drm_connector_fops = { > + .owner = THIS_MODULE, > + .open = connector_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > + .write = connector_write > +}; > + > +int drm_debugfs_connector_add(struct drm_connector *connector) > +{ > + struct drm_minor *minor = connector->dev->primary; > + struct dentry *root, *ent; > + > + if (!minor->debugfs_root) > + return -1; > + > + root = debugfs_create_dir(drm_get_connector_name(connector), > + minor->debugfs_root); > + if (!root) > + return -ENOMEM; > + > + connector->debugfs_entry = root; > + > + /* force */ > + ent = debugfs_create_file("force", S_IRUGO, root, connector, > + &drm_connector_fops); > + if (!ent) > + return -ENOMEM; You need to cleanup connector->debugfs_entry here as you're not doing that in drm_connector_add(). Thanks David > + > + return 0; > +} > + > +void drm_debugfs_connector_remove(struct drm_connector *connector) > +{ > + if (!connector->debugfs_entry) > + return; > + > + debugfs_remove_recursive(connector->debugfs_entry); > + > + connector->debugfs_entry = NULL; > +} > + > #endif /* CONFIG_DEBUG_FS */ > > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 76ccaab..c6c85f7 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -1425,6 +1425,8 @@ extern int drm_debugfs_create_files(const struct drm_info_list *files, > extern int drm_debugfs_remove_files(const struct drm_info_list *files, > int count, struct drm_minor *minor); > extern int drm_debugfs_cleanup(struct drm_minor *minor); > +extern int drm_debugfs_connector_add(struct drm_connector *connector); > +extern void drm_debugfs_connector_remove(struct drm_connector *connector); > #else > static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id, > struct dentry *root) > @@ -1449,6 +1451,15 @@ static inline int drm_debugfs_cleanup(struct drm_minor *minor) > { > return 0; > } > + > +static inline int drm_debugfs_connector_add(struct drm_connector *connector) > +{ > + return 0; > +} > +static inline void drm_debugfs_connector_remove(struct drm_connector *connector) > +{ > +} > + > #endif > > /* Info file support */ > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 51e6255..f04f4b9 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -525,6 +525,8 @@ struct drm_connector { > int audio_latency[2]; > int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ > unsigned bad_edid_counter; > + > + struct dentry *debugfs_entry; > }; > > /** > -- > 1.9.0 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
The following patches update the last two patches in the original series with the suggested changes from David Herrmann. Thomas Wood (2): drm/debugfs: add a "force" file per connector drm/debugfs: add an "edid_override" file per connector drivers/gpu/drm/drm_crtc.c | 21 ++++- drivers/gpu/drm/drm_debugfs.c | 182 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 9 +- include/drm/drmP.h | 11 +++ include/drm/drm_crtc.h | 3 + 5 files changed, 224 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 998663c..59a2784 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -841,6 +841,8 @@ int drm_connector_init(struct drm_device *dev, drm_object_attach_property(&connector->base, dev->mode_config.dpms_property, 0); + connector->debugfs_entry = NULL; + out_put: if (ret) drm_mode_object_put(dev, &connector->base); @@ -891,7 +893,19 @@ EXPORT_SYMBOL(drm_connector_cleanup); */ int drm_connector_register(struct drm_connector *connector) { - return drm_sysfs_connector_add(connector); + int ret; + + ret = drm_sysfs_connector_add(connector); + if (ret != 0) + return ret; + + ret = drm_debugfs_connector_add(connector); + if (ret != 0) { + drm_sysfs_connector_remove(connector); + return ret; + } + + return 0; } EXPORT_SYMBOL(drm_connector_register); @@ -904,6 +918,7 @@ EXPORT_SYMBOL(drm_connector_register); void drm_connector_unregister(struct drm_connector *connector) { drm_sysfs_connector_remove(connector); + drm_debugfs_connector_remove(connector); } EXPORT_SYMBOL(drm_connector_unregister); diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index b4b51d4..b57b614 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -237,5 +237,106 @@ int drm_debugfs_cleanup(struct drm_minor *minor) return 0; } +static int connector_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + const char *status; + + switch (connector->force) { + case DRM_FORCE_ON: + status = "on\n"; + break; + + case DRM_FORCE_ON_DIGITAL: + status = "digital\n"; + break; + + case DRM_FORCE_OFF: + status = "off\n"; + break; + + case DRM_FORCE_UNSPECIFIED: + status = "unspecified\n"; + break; + + default: + return 0; + } + + seq_puts(m, status); + + return 0; +} + +static int connector_open(struct inode *inode, struct file *file) +{ + struct drm_connector *dev = inode->i_private; + + return single_open(file, connector_show, dev); +} + +static ssize_t connector_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct drm_connector *connector = m->private; + + if (strncmp(ubuf, "on", len) == 0) + connector->force = DRM_FORCE_ON; + else if (strncmp(ubuf, "digital", len) == 0) + connector->force = DRM_FORCE_ON_DIGITAL; + else if (strncmp(ubuf, "off", len) == 0) + connector->force = DRM_FORCE_OFF; + else if (strncmp(ubuf, "unspecified", len) == 0) + connector->force = DRM_FORCE_UNSPECIFIED; + else + return -EINVAL; + + return len; +} + +static const struct file_operations drm_connector_fops = { + .owner = THIS_MODULE, + .open = connector_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = connector_write +}; + +int drm_debugfs_connector_add(struct drm_connector *connector) +{ + struct drm_minor *minor = connector->dev->primary; + struct dentry *root, *ent; + + if (!minor->debugfs_root) + return -1; + + root = debugfs_create_dir(drm_get_connector_name(connector), + minor->debugfs_root); + if (!root) + return -ENOMEM; + + connector->debugfs_entry = root; + + /* force */ + ent = debugfs_create_file("force", S_IRUGO, root, connector, + &drm_connector_fops); + if (!ent) + return -ENOMEM; + + return 0; +} + +void drm_debugfs_connector_remove(struct drm_connector *connector) +{ + if (!connector->debugfs_entry) + return; + + debugfs_remove_recursive(connector->debugfs_entry); + + connector->debugfs_entry = NULL; +} + #endif /* CONFIG_DEBUG_FS */ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 76ccaab..c6c85f7 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1425,6 +1425,8 @@ extern int drm_debugfs_create_files(const struct drm_info_list *files, extern int drm_debugfs_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor); extern int drm_debugfs_cleanup(struct drm_minor *minor); +extern int drm_debugfs_connector_add(struct drm_connector *connector); +extern void drm_debugfs_connector_remove(struct drm_connector *connector); #else static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root) @@ -1449,6 +1451,15 @@ static inline int drm_debugfs_cleanup(struct drm_minor *minor) { return 0; } + +static inline int drm_debugfs_connector_add(struct drm_connector *connector) +{ + return 0; +} +static inline void drm_debugfs_connector_remove(struct drm_connector *connector) +{ +} + #endif /* Info file support */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 51e6255..f04f4b9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -525,6 +525,8 @@ struct drm_connector { int audio_latency[2]; int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ unsigned bad_edid_counter; + + struct dentry *debugfs_entry; }; /**
Add a file to debugfs for each connector to enable modification of the "force" connector attribute. This allows connectors to be enabled or disabled for testing and debugging purposes. Signed-off-by: Thomas Wood <thomas.wood@intel.com> --- drivers/gpu/drm/drm_crtc.c | 17 ++++++- drivers/gpu/drm/drm_debugfs.c | 101 ++++++++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 11 +++++ include/drm/drm_crtc.h | 2 + 4 files changed, 130 insertions(+), 1 deletion(-)