The accelerator devices will be exposed to the user space with a new, dedicated major number - 261. The drm core registers the new major number as a char device and create corresponding sysfs and debugfs root entries, same as for the drm major. In case CONFIG_ACCEL is not selected, this code is not compiled in. Signed-off-by: Oded Gabbay <ogabbay@xxxxxxxxxx> --- Documentation/admin-guide/devices.txt | 5 +++ drivers/gpu/drm/drm_drv.c | 45 +++++++++++++++++++++++ drivers/gpu/drm/drm_internal.h | 3 ++ drivers/gpu/drm/drm_sysfs.c | 52 +++++++++++++++++++++++++++ include/drm/drm_ioctl.h | 1 + 5 files changed, 106 insertions(+) diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 9764d6edb189..06c525e01ea5 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -3080,6 +3080,11 @@ ... 255 = /dev/osd255 256th OSD Device + 261 char Compute Acceleration Devices + 0 = /dev/accel/accel0 First acceleration device + 1 = /dev/accel/accel1 Second acceleration device + ... + 384-511 char RESERVED FOR DYNAMIC ASSIGNMENT Character devices that request a dynamic allocation of major number will take numbers starting from 511 and downward, diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8214a0b1ab7f..b58ffb1433d6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -67,6 +67,10 @@ static bool drm_core_init_complete; static struct dentry *drm_debugfs_root; +#ifdef CONFIG_ACCEL +static struct dentry *accel_debugfs_root; +#endif + DEFINE_STATIC_SRCU(drm_unplug_srcu); /* @@ -1031,9 +1035,19 @@ static const struct file_operations drm_stub_fops = { .llseek = noop_llseek, }; +static void accel_core_exit(void) +{ +#ifdef CONFIG_ACCEL + unregister_chrdev(ACCEL_MAJOR, "accel"); + debugfs_remove(accel_debugfs_root); + accel_sysfs_destroy(); +#endif +} + static void drm_core_exit(void) { drm_privacy_screen_lookup_exit(); + accel_core_exit(); unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); drm_sysfs_destroy(); @@ -1041,6 +1055,33 @@ static void drm_core_exit(void) drm_connector_ida_destroy(); } +static int __init accel_core_init(void) +{ +#ifdef CONFIG_ACCEL + int ret; + + ret = accel_sysfs_init(); + if (ret < 0) { + DRM_ERROR("Cannot create ACCEL class: %d\n", ret); + goto error; + } + + accel_debugfs_root = debugfs_create_dir("accel", NULL); + + ret = register_chrdev(ACCEL_MAJOR, "accel", &drm_stub_fops); + if (ret < 0) + goto error; + +error: + /* Any cleanup will be done in drm_core_exit() that will call + * to accel_core_exit() + */ + return ret; +#else + return 0; +#endif +} + static int __init drm_core_init(void) { int ret; @@ -1061,6 +1102,10 @@ static int __init drm_core_init(void) if (ret < 0) goto error; + ret = accel_core_init(); + if (ret < 0) + goto error; + drm_privacy_screen_lookup_init(); drm_core_init_complete = true; diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 7bb98e6a446d..cbeb9bd3c312 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -147,9 +147,12 @@ void drm_master_internal_release(struct drm_device *dev); /* drm_sysfs.c */ extern struct class *drm_class; +extern struct class *accel_class; int drm_sysfs_init(void); void drm_sysfs_destroy(void); +int accel_sysfs_init(void); +void accel_sysfs_destroy(void); struct device *drm_sysfs_minor_alloc(struct drm_minor *minor); int drm_sysfs_connector_add(struct drm_connector *connector); void drm_sysfs_connector_remove(struct drm_connector *connector); diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 430e00b16eec..70b2a28f55c4 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -56,6 +56,7 @@ static struct device_type drm_sysfs_device_connector = { }; struct class *drm_class; +struct class *accel_class; #ifdef CONFIG_ACPI static bool drm_connector_acpi_bus_match(struct device *dev) @@ -148,6 +149,57 @@ static void drm_sysfs_release(struct device *dev) kfree(dev); } +static char *accel_devnode(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "accel/%s", dev_name(dev)); +} + +static CLASS_ATTR_STRING(accel_version, 0444, "accel 1.0.0 20221018"); + +/** + * accel_sysfs_init - initialize sysfs helpers + * + * This is used to create the ACCEL class, which is the implicit parent of any + * other top-level ACCEL sysfs objects. + * + * You must call accel_sysfs_destroy() to release the allocated resources. + * + * Return: 0 on success, negative error code on failure. + */ +int accel_sysfs_init(void) +{ + int err; + + accel_class = class_create(THIS_MODULE, "accel"); + if (IS_ERR(accel_class)) + return PTR_ERR(accel_class); + + err = class_create_file(accel_class, &class_attr_accel_version.attr); + if (err) { + class_destroy(accel_class); + accel_class = NULL; + return err; + } + + accel_class->devnode = accel_devnode; + + return 0; +} + +/** + * accel_sysfs_destroy - destroys ACCEL class + * + * Destroy the ACCEL device class. + */ +void accel_sysfs_destroy(void) +{ + if (IS_ERR_OR_NULL(accel_class)) + return; + class_remove_file(accel_class, &class_attr_accel_version.attr); + class_destroy(accel_class); + accel_class = NULL; +} + /* * Connector properties */ diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h index 6ed61c371f6c..88e4926208e7 100644 --- a/include/drm/drm_ioctl.h +++ b/include/drm/drm_ioctl.h @@ -70,6 +70,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, #define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_IOCTL_TYPE(n) _IOC_TYPE(n) #define DRM_MAJOR 226 +#define ACCEL_MAJOR 261 /** * enum drm_ioctl_flags - DRM ioctl flags -- 2.34.1