This will be of great help when testing potential races between the GPU reset sequence and other parts of the code accessing HW registers.
Signed-off-by: Adrián Larumbe <[email protected]> --- drivers/gpu/drm/panfrost/panfrost_device.c | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index d75566a45392..0aee1d87a7ab 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -2,6 +2,7 @@ /* Copyright 2018 Marty E. Plummer <[email protected]> */ /* Copyright 2019 Linaro, Ltd, Rob Herring <[email protected]> */ +#include <linux/debugfs.h> #include <linux/clk.h> #include <linux/reset.h> #include <linux/platform_device.h> @@ -583,9 +584,45 @@ EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { }; #ifdef CONFIG_DEBUG_FS +static int reset_get(void *data, u64 *val) +{ + struct panfrost_device *pfdev = + container_of(data, struct panfrost_device, base); + + *val = atomic_read(&pfdev->reset.pending); + return 0; +} + +static int reset_set(void *data, u64 val) +{ + struct panfrost_device *pfdev = + container_of(data, struct panfrost_device, base); + int ret = pm_runtime_get_if_active(pfdev->base.dev); + + if (ret) { + panfrost_device_schedule_reset(pfdev); + flush_work(&pfdev->reset.work); + if (ret > 0) + pm_runtime_put(pfdev->base.dev); + } + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(panfrost_reset_debugfs_fops, + reset_get, reset_set, + "0x%08llx\n"); + +static void panfrost_reset_debugfs_init(struct drm_minor *minor) +{ + debugfs_create_file("reset", 0600, minor->debugfs_root, + minor->dev, &panfrost_reset_debugfs_fops); +} + void panfrost_device_debugfs_init(struct drm_minor *minor) { panfrost_gem_debugfs_init(minor); panfrost_sched_debugfs_init(minor); + panfrost_reset_debugfs_init(minor); } #endif // CONFIG_DEBUG_FS -- 2.55.0
