diff options
Diffstat (limited to 'drivers/gpu/drm/drm_sysfs.c')
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 3c22a803201d..f62767ff34b2 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -11,12 +11,14 @@ */ #include <linux/acpi.h> +#include <linux/component.h> #include <linux/device.h> #include <linux/err.h> #include <linux/export.h> #include <linux/gfp.h> #include <linux/i2c.h> #include <linux/kdev_t.h> +#include <linux/property.h> #include <linux/slab.h> #include <drm/drm_accel.h> @@ -96,6 +98,34 @@ static char *drm_devnode(const struct device *dev, umode_t *mode) return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); } +static int typec_connector_bind(struct device *dev, + struct device *typec_connector, void *data) +{ + int ret; + + ret = sysfs_create_link(&dev->kobj, &typec_connector->kobj, "typec_connector"); + if (ret) + return ret; + + ret = sysfs_create_link(&typec_connector->kobj, &dev->kobj, "drm_connector"); + if (ret) + sysfs_remove_link(&dev->kobj, "typec_connector"); + + return ret; +} + +static void typec_connector_unbind(struct device *dev, + struct device *typec_connector, void *data) +{ + sysfs_remove_link(&typec_connector->kobj, "drm_connector"); + sysfs_remove_link(&dev->kobj, "typec_connector"); +} + +static const struct component_ops typec_connector_ops = { + .bind = typec_connector_bind, + .unbind = typec_connector_unbind, +}; + static CLASS_ATTR_STRING(version, S_IRUGO, "drm 1.1.0 20060810"); /** @@ -282,16 +312,27 @@ static ssize_t modes_show(struct device *device, return written; } +static ssize_t connector_id_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_connector *connector = to_drm_connector(device); + + return sysfs_emit(buf, "%d\n", connector->base.id); +} + static DEVICE_ATTR_RW(status); static DEVICE_ATTR_RO(enabled); static DEVICE_ATTR_RO(dpms); static DEVICE_ATTR_RO(modes); +static DEVICE_ATTR_RO(connector_id); static struct attribute *connector_dev_attrs[] = { &dev_attr_status.attr, &dev_attr_enabled.attr, &dev_attr_dpms.attr, &dev_attr_modes.attr, + &dev_attr_connector_id.attr, NULL }; @@ -353,9 +394,16 @@ int drm_sysfs_connector_add(struct drm_connector *connector) connector->kdev = kdev; + if (dev_fwnode(kdev)) { + r = component_add(kdev, &typec_connector_ops); + if (r) + drm_err(dev, "failed to add component to create link to typec connector\n"); + } + if (connector->ddc) return sysfs_create_link(&connector->kdev->kobj, &connector->ddc->dev.kobj, "ddc"); + return 0; err_free: @@ -371,6 +419,9 @@ void drm_sysfs_connector_remove(struct drm_connector *connector) if (connector->ddc) sysfs_remove_link(&connector->kdev->kobj, "ddc"); + if (dev_fwnode(connector->kdev)) + component_del(connector->kdev, &typec_connector_ops); + DRM_DEBUG("removing \"%s\" from sysfs\n", connector->name); |