/* * drm_sysfs.c - Modifications to drm_sysfs_class.c to support * extra sysfs attribute from DRM. Normal drm_sysfs_class * does not allow adding attributes. * * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com> * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com> * Copyright (c) 2003-2004 IBM Corp.
*/
/** * DOC: overview * * DRM provides very little additional support to drivers for sysfs * interactions, beyond just all the standard stuff. Drivers who want to expose * additional sysfs properties and property groups can attach them at either * &drm_device.dev or &drm_connector.kdev. * * Registration is automatically handled when calling drm_dev_register(), or * drm_connector_register() in case of hot-plugged connectors. Unregistration is * also automatically handled by drm_dev_unregister() and * drm_connector_unregister().
*/
/** * drm_sysfs_init - initialize sysfs helpers * * This is used to create the DRM class, which is the implicit parent of any * other top-level DRM sysfs objects. * * You must call drm_sysfs_destroy() to release the allocated resources. * * Return: 0 on success, negative error code on failure.
*/ int drm_sysfs_init(void)
{ int err;
drm_class = class_create("drm"); if (IS_ERR(drm_class)) return PTR_ERR(drm_class);
if (old_force != connector->force || !connector->force) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
connector->base.id, connector->name,
old_force, connector->force);
r = dev_set_name(kdev, "card%d-%s", dev->primary->index, connector->name); if (r) goto err_free;
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] adding connector to sysfs\n",
connector->base.id, connector->name);
r = device_add(kdev); if (r) {
drm_err(dev, "failed to register connector device: %d\n", r); goto err_free;
}
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");
}
return 0;
err_free:
put_device(kdev); return r;
}
int drm_sysfs_connector_add_late(struct drm_connector *connector)
{ if (connector->ddc) return sysfs_create_link(&connector->kdev->kobj,
&connector->ddc->dev.kobj, "ddc");
return 0;
}
void drm_sysfs_connector_remove_early(struct drm_connector *connector)
{ if (connector->ddc)
sysfs_remove_link(&connector->kdev->kobj, "ddc");
}
void drm_sysfs_connector_remove(struct drm_connector *connector)
{ if (!connector->kdev) return;
if (dev_fwnode(connector->kdev))
component_del(connector->kdev, &typec_connector_ops);
drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] removing connector from sysfs\n",
connector->base.id, connector->name);
/** * drm_sysfs_hotplug_event - generate a DRM uevent * @dev: DRM device * * Send a uevent for the DRM device specified by @dev. Currently we only * set HOTPLUG=1 in the uevent environment, but this could be expanded to * deal with other types of events. * * Any new uapi should be using the drm_sysfs_connector_status_event() * for uevents on connector status change.
*/ void drm_sysfs_hotplug_event(struct drm_device *dev)
{ char *event_string = "HOTPLUG=1"; char *envp[] = { event_string, NULL };
/** * drm_sysfs_connector_hotplug_event - generate a DRM uevent for any connector * change * @connector: connector which has changed * * Send a uevent for the DRM connector specified by @connector. This will send * a uevent with the properties HOTPLUG=1 and CONNECTOR.
*/ void drm_sysfs_connector_hotplug_event(struct drm_connector *connector)
{ struct drm_device *dev = connector->dev; char hotplug_str[] = "HOTPLUG=1", conn_id[21]; char *envp[] = { hotplug_str, conn_id, NULL };
/** * drm_sysfs_connector_property_event - generate a DRM uevent for connector * property change * @connector: connector on which property changed * @property: connector property which has changed. * * Send a uevent for the specified DRM connector and property. Currently we * set HOTPLUG=1 and connector id along with the attached property id * related to the change.
*/ void drm_sysfs_connector_property_event(struct drm_connector *connector, struct drm_property *property)
{ struct drm_device *dev = connector->dev; char hotplug_str[] = "HOTPLUG=1", conn_id[21], prop_id[21]; char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
r = dev_set_name(kdev, minor_str, minor->index); if (r < 0) goto err_free;
return kdev;
err_free:
put_device(kdev); return ERR_PTR(r);
}
/** * drm_class_device_register - register new device with the DRM sysfs class * @dev: device to register * * Registers a new &struct device within the DRM sysfs class. Essentially only * used by ttm to have a place for its global settings. Drivers should never use * this.
*/ int drm_class_device_register(struct device *dev)
{ if (!drm_class || IS_ERR(drm_class)) return -ENOENT;
/** * drm_class_device_unregister - unregister device with the DRM sysfs class * @dev: device to unregister * * Unregisters a &struct device from the DRM sysfs class. Essentially only used * by ttm to have a place for its global settings. Drivers should never use * this.
*/ void drm_class_device_unregister(struct device *dev)
{ return device_unregister(dev);
}
EXPORT_SYMBOL_GPL(drm_class_device_unregister);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.