I've tried poking the knob that fakes an error in the reset path and got two different kinds of oputput:
Either ``` [ 1950.080236] panthor fb000000.gpu: [drm] *ERROR* Failed to boot MCU after reset, making device unusable. [ 1951.167384] panthor fb000000.gpu: [drm] Timed out waiting for MCU to halt [ 1951.167543] panthor fb000000.gpu: [drm] Failed to cleanly suspend MCU ``` or just ``` [ 2022.804466] panthor fb000000.gpu: [drm] *ERROR* Failed to boot MCU after reset, making device unusable. ``` I guess the former happens when after device unplug, there are still inflight jobs that keep a PM reference. On 26.08.2026 16:56, Boris Brezillon wrote: > It's almost impossible to trigger a situation where the reset > doesn't work now that the driver is more mature, so let's add two > knobs to exercise this error path: > > - a knob to trigger a reset > - a knob to fake an error in the reset path > > Signed-off-by: Boris Brezillon <[email protected]> > --- > drivers/gpu/drm/panthor/panthor_device.c | 48 > +++++++++++++++++++++++++++++++- > drivers/gpu/drm/panthor/panthor_device.h | 8 ++++++ > 2 files changed, 55 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panthor/panthor_device.c > b/drivers/gpu/drm/panthor/panthor_device.c > index 328e601d80e8..8bdc511310c0 100644 > --- a/drivers/gpu/drm/panthor/panthor_device.c > +++ b/drivers/gpu/drm/panthor/panthor_device.c > @@ -5,6 +5,7 @@ > /* Copyright 2025 ARM Limited. All rights reserved. */ > > #include <linux/clk.h> > +#include <linux/debugfs.h> > #include <linux/mm.h> > #include <linux/platform_device.h> > #include <linux/pm_domain.h> > @@ -182,7 +183,10 @@ static void panthor_device_reset_work(struct work_struct > *work) > panthor_hw_soft_reset(ptdev); > panthor_hw_l2_power_on(ptdev); > panthor_mmu_post_reset(ptdev); > - ret = panthor_fw_post_reset(ptdev); > + if (ptdev->reset.fake_failure) > + ret = -EIO; > + else > + ret = panthor_fw_post_reset(ptdev); > atomic_set(&ptdev->reset.pending, 0); > panthor_sched_post_reset(ptdev, ret != 0); > drm_dev_exit(cookie); > @@ -690,8 +694,50 @@ int panthor_device_suspend(struct device *dev) > } > > #ifdef CONFIG_DEBUG_FS > +static int panthor_device_fake_fw_reset_failure_get(void *data, u64 *val) > +{ > + struct panthor_device *ptdev = data; > + > + *val = ptdev->reset.fake_failure ? 1 : 0; > + return 0; > +} > + > +static int panthor_device_fake_fw_reset_failure_set(void *data, u64 val) > +{ > + struct panthor_device *ptdev = data; > + > + ptdev->reset.fake_failure = val ? true : false; > + return 0; > +} > + > +DEFINE_DEBUGFS_ATTRIBUTE(panthor_device_fake_fw_reset_failure_fops, > + panthor_device_fake_fw_reset_failure_get, > + panthor_device_fake_fw_reset_failure_set, "%llu\n"); > + > +static ssize_t panthor_device_reset_file_write(struct file *file, > + const char __user *, size_t size, > + loff_t *) > +{ > + struct panthor_device *ptdev = file_inode(file)->i_private; > + > + panthor_device_schedule_reset(ptdev); > + return size; > +} > + > +static const struct debugfs_short_fops panthor_device_reset_fops = { > + .write = panthor_device_reset_file_write, > +}; > + > void panthor_device_debugfs_init(struct drm_minor *minor) > { > + struct panthor_device *ptdev = container_of(minor->dev, struct > panthor_device, base); > + > + debugfs_create_file("fake_fw_reset_failure", 0644, > + minor->debugfs_root, ptdev, > + &panthor_device_fake_fw_reset_failure_fops); > + debugfs_create_file("reset", 0200, > + minor->debugfs_root, ptdev, > + &panthor_device_reset_fops); > panthor_mmu_debugfs_init(minor); > panthor_gem_debugfs_init(minor); > } > diff --git a/drivers/gpu/drm/panthor/panthor_device.h > b/drivers/gpu/drm/panthor/panthor_device.h > index e12049961912..82ec34347eba 100644 > --- a/drivers/gpu/drm/panthor/panthor_device.h > +++ b/drivers/gpu/drm/panthor/panthor_device.h > @@ -294,6 +294,14 @@ struct panthor_device { > * all FW sections to make sure we start from a fresh state. > */ > bool fast; > + > + /** > + * @fake_failure: When true, pretend the FW boot in the reset > path failed. > + * > + * This is important to check that we're doing the right thing > in this very > + * unlikely case. > + */ > + bool fake_failure; > } reset; > > /** @pm: Power management related data. */ > > -- > 2.55.0 Adrian Larumbe
