accel: add accel dummy driver This commit is only intended as a reference of how to add a new accelerator driver. It is not intended to be merged. The dummy driver defines the new DRIVER_COMPUTE_ACCEL flag as its feature and registers to the DRM subsystem. Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
diff --git a/drivers/Makefile b/drivers/Makefile index bdf1c66..d2de100 100644 --- a/drivers/Makefile +++ b/drivers/Makefile
@@ -62,6 +62,9 @@ # gpu/ comes after char for AGP vs DRM startup and after iommu obj-y += gpu/ +# accel is part of drm so it must come after gpu +obj-$(CONFIG_DRM_ACCEL) += accel/ + obj-$(CONFIG_CONNECTOR) += connector/ # i810fb and intelfb depend on char/agp/
diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig index c9ce849..4fc7729 100644 --- a/drivers/accel/Kconfig +++ b/drivers/accel/Kconfig
@@ -22,3 +22,5 @@ major number than GPUs, and will be exposed to user-space using different device files, called accel/accel* (in /dev, sysfs and debugfs). + +source "drivers/accel/dummy/Kconfig"
diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile new file mode 100644 index 0000000..0477cb9 --- /dev/null +++ b/drivers/accel/Makefile
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Makefile for the accel framework. This framework provides support for +# compute acceleration devices, such as, but not limited to, Machine-Learning +# and Deep-Learning acceleration devices + +obj-$(CONFIG_ACCEL_DUMMY) += dummy/
diff --git a/drivers/accel/dummy/Kconfig b/drivers/accel/dummy/Kconfig new file mode 100644 index 0000000..5b871b0 --- /dev/null +++ b/drivers/accel/dummy/Kconfig
@@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +config ACCEL_DUMMY + tristate "Drive for a dummy compute accelerator" + depends on DRM_ACCEL + help + An example of a compute accelerator driver that registers with drm + as a compute accelerator. + + This driver does not actually do anything. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called accel_dummy.
diff --git a/drivers/accel/dummy/Makefile b/drivers/accel/dummy/Makefile new file mode 100644 index 0000000..c2b9706 --- /dev/null +++ b/drivers/accel/dummy/Makefile
@@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +accel_dummy-y += dummy_drv.o + +obj-$(CONFIG_ACCEL_DUMMY) := accel_dummy.o
diff --git a/drivers/accel/dummy/dummy_drv.c b/drivers/accel/dummy/dummy_drv.c new file mode 100644 index 0000000..1852577 --- /dev/null +++ b/drivers/accel/dummy/dummy_drv.c
@@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/dma-mapping.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <drm/drm_accel.h> +#include <drm/drm_drv.h> +#include <drm/drm_ioctl.h> +#include <drm/drm_print.h> + +#define DRIVER_NAME "accel_dummy" +#define DRIVER_DESC "Driver for a dummy compute accelerator" +#define DRIVER_DATE "20221022" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 + +MODULE_AUTHOR("Oded Gabbay"); +MODULE_DESCRIPTION("Driver for a dummy compute accelerator"); +MODULE_LICENSE("GPL"); + +static void accel_dummy_debugfs_init(struct drm_minor *minor); + +static struct platform_device *accel_dummy_drm; + +DEFINE_DRM_ACCEL_FOPS(accel_dummy_driver_fops); + +static const struct drm_driver accel_dummy_drm_driver = { + .driver_features = DRIVER_COMPUTE_ACCEL, + .fops = &accel_dummy_driver_fops, + .debugfs_init = accel_dummy_debugfs_init, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, +}; + +static void accel_dummy_debugfs_init(struct drm_minor *minor) +{ + DRM_INFO("%s called\n", __func__); +} + +static int accel_dummy_pdev_probe(struct platform_device *pdev) +{ + struct drm_device *drm; + struct device *dev; + int ret; + + DRM_INFO("%s called\n", __func__); + + dev = &pdev->dev; + + drm = drm_dev_alloc(&accel_dummy_drm_driver, dev); + if (IS_ERR(drm)) + return PTR_ERR(drm); + + dma_set_max_seg_size(dev, SZ_2G); + + dev_set_drvdata(dev, drm); + + ret = drm_dev_register(drm, 0); + if (ret) + goto out_put; + + return 0; + +out_put: + drm_dev_put(drm); + + return ret; +} + +static int accel_dummy_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct drm_device *drm = dev_get_drvdata(dev); + + DRM_INFO("%s called\n", __func__); + + drm_dev_unregister(drm); + + drm_dev_put(drm); + + return 0; +} + +static struct platform_driver accel_dummy_platform_driver = { + .probe = accel_dummy_pdev_probe, + .remove = accel_dummy_remove, + .driver = { + .name = "accel_dummy", + }, +}; + +static void __exit accel_dummy_exit(void) +{ + DRM_INFO("%s called\n", __func__); + + if (IS_ERR_OR_NULL(accel_dummy_drm)) { + DRM_INFO("accel_dummy_drm wasn't initialized\n"); + return; + } + + platform_device_unregister(accel_dummy_drm); + platform_driver_unregister(&accel_dummy_platform_driver); + + accel_dummy_drm = NULL; +} + +static int __init accel_dummy_init(void) +{ + struct platform_device *pdev; + int ret; + + DRM_INFO("%s called\n", __func__); + + ret = platform_driver_register(&accel_dummy_platform_driver); + if (ret != 0) + return ret; + + pdev = platform_device_alloc("accel_dummy", PLATFORM_DEVID_NONE); + if (!pdev) { + ret = -ENOMEM; + goto unregister_platform_driver; + } + + ret = platform_device_add(pdev); + if (ret) { + platform_device_put(pdev); + goto unregister_platform_driver; + } + + accel_dummy_drm = pdev; + + return 0; + +unregister_platform_driver: + platform_driver_unregister(&accel_dummy_platform_driver); + return ret; +} + +module_init(accel_dummy_init); +module_exit(accel_dummy_exit);