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 | 39 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/panfrost/panfrost_device.h |  3 +++
 drivers/gpu/drm/panfrost/panfrost_drv.c    |  1 +
 3 files changed, 43 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index 52f4b8c6a05f..5b66173c75b9 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>
@@ -608,3 +609,41 @@ void panfrost_device_reset(struct panfrost_device *pfdev, 
bool enable_job_int)
        if (enable_job_int)
                panfrost_jm_enable_interrupts(pfdev);
 }
+
+#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;
+
+       ret = pm_runtime_get_if_in_use(pfdev->base.dev);
+
+       if (ret > 0) {
+               panfrost_device_schedule_reset(pfdev);
+               flush_work(&pfdev->reset.work);
+               pm_runtime_put(pfdev->base.dev);
+       }
+
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(panfrost_reset_debugfs_fops,
+                        reset_get, reset_set,
+                        "0x%08llx\n");
+
+void panfrost_reset_debugfs_init(struct drm_minor *minor)
+{
+       debugfs_create_file("reset", 0600, minor->debugfs_root,
+                           minor->dev, &panfrost_reset_debugfs_fops);
+}
+#endif // CONFIG_DEBUG_FS
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 0fd33bc5b86f..4bbaaaf827a5 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -350,4 +350,7 @@ panfrost_device_started(struct panfrost_device *pfdev)
        return pfdev->js;
 }
 
+#ifdef CONFIG_DEBUG_FS
+void panfrost_reset_debugfs_init(struct drm_minor *minor);
+#endif // CONFIG_DEBUG_FS
 #endif
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 8410de95e364..958f1d36ab10 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -916,6 +916,7 @@ static void panfrost_debugfs_init(struct drm_minor *minor)
 {
        panthor_gems_debugfs_init(minor);
        panfrost_sched_debugfs_init(minor);
+       panfrost_reset_debugfs_init(minor);
 }
 #endif
 

-- 
2.55.0

Reply via email to