AMD General
Regards,
Prike
> -----Original Message-----
> From: Liu, Leo <[email protected]>
> Sent: Tuesday, November 3, 2026 12:22 AM
> To: Liang, Prike <[email protected]>; [email protected]
> Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
> <[email protected]>; Lazar, Lijo <[email protected]>; Prosyak, Vitaly
> <[email protected]>; Liang, Prike <[email protected]>; Lazar, Lijo
> <[email protected]>
> Subject: RE: [PATCH 3/3] drm/amdgpu: stop GPU recovery wait for the JPEG/VCN
> idle work
>
> AMD General
>
> > -----Original Message-----
> > From: amd-gfx <[email protected]> On Behalf Of
> > Prike Liang
> > Sent: Thursday, October 29, 2026 10:48 PM
> > To: [email protected]
> > Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
> > <[email protected]>; Lazar, Lijo <[email protected]>; Prosyak,
> > Vitaly <[email protected]>; Liang, Prike <[email protected]>;
> > Lazar, Lijo <[email protected]>
> > Subject: [PATCH 3/3] drm/amdgpu: stop GPU recovery wait for the
> > JPEG/VCN idle work
> >
> > The common JPEG and VCN idle workers program power gating and DPG
> > pause, so they must not run while a GPU reset is in progress. Recovery
> > must not wait for them either, since everything the workers depend on
> > then becomes a dependency of GPU recovery.
> >
> > Make the workers take reset_domain->sem for read, so they wait for a
> > running reset instead of touching the hardware. hw_fini/suspend, the
> > hw_init error paths and begin_use, the latter for the IB tests, run
> > from GPU recovery as well, so only skip waiting for the idle work when
> > the reset itself calls them. The reset holds the semaphore for write
> > and would otherwise deadlock on a worker blocked on it. Outside a
> > reset the cancel stays synchronous as before.
> >
> > A device can also be torn down while a peer in its XGMI reset domain
> > is being reset. hw_fini then doesn't wait for the worker either, and
> > is skipped entirely if the peer's reset has already suspended the device.
> > Cancel the idle work synchronously in early_fini, which only runs on
> > teardown and before any hw_fini, so the worker is done before the
> > hardware it touches is torn down.
> >
> > Update versions:
> > v1: https://lists.freedesktop.org/archives/amd-gfx/2026-
> > October/155441.html
> > v2: https://lists.freedesktop.org/archives/amd-gfx/2026-
> > October/156119.html
> >
> > Signed-off-by: Prike Liang <[email protected]> Cc; Leo Liu
> > <[email protected]>
> > Reviewed-by: Lijo Lazar <[email protected]>
> > ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c | 30
> > ++++++++++++++++++--
> > drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h | 1 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 36
> > +++++++++++++++++++++++-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 2 ++
> > drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 6 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 4 +--
> > drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 4 +--
> > drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 5 ++--
> > drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c | 5 ++--
> > 24 files changed, 125 insertions(+), 43 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
> > index 2b0e658b63b6..87f0ba6a79d6 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
> > @@ -95,9 +95,30 @@ int amdgpu_jpeg_sw_fini(struct amdgpu_device
> > *adev)
> > return 0;
> > }
> >
> > +int amdgpu_jpeg_early_fini(struct amdgpu_ip_block *ip_block) {
> > + /* Called on teardown even if sw_init never ran */
> > + if (!ip_block->status.sw)
> > + return 0;
> > +
> > + /* hw_fini may not wait while a peer in the reset domain resets */
> > + cancel_delayed_work_sync(&ip_block->adev->jpeg.idle_work);
> > +
>
> With early_fini(), hw_fini(), suspend() and sw_fini() now all potentially
> calling the
> cancel for the different fini paths, the cancel now happens multiple times
> without
> explicit conditions to make clear when each call is actually needed.
> For example, on the normal unload/teardown path, early_fini() cancels
> synchronously, then hw_fini() cancels again (no-op), then sw_fini() cancels
> again
> (no-op). It would be cleaner to add an explicit condition at each call.
Agreed. The repeated cancels in the *_fini callbacks are harmless no-ops,
but they look duplicated and don't make clear which path needs them. To
keep this readable, I'll cancel the idle work in one place per path:
early_fini() for teardown, and hw_fini() for suspend and GPU reset (only
when !adev->shutdown). I'll also remove the cancels from sw_fini() and
the JPEG suspend(), and send the update in the next version of the patch.
Thanks,
Prike
> Thanks,
> Leo
>
>
> > + return 0;
> > +}
> > +
> > +static void amdgpu_jpeg_cancel_idle_work(struct amdgpu_device *adev)
> > +{
> > + /* The reset mustn't wait for the idle work, which waits for the
> > reset */
> > + if (amdgpu_in_reset(adev))
> > + cancel_delayed_work(&adev->jpeg.idle_work);
> > + else
> > + cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > +}
> > +
> > int amdgpu_jpeg_suspend(struct amdgpu_device *adev) {
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_cancel_idle_work(adev);
> >
> > return 0;
> > }
> > @@ -114,6 +135,9 @@ static void amdgpu_jpeg_idle_work_handler(struct
> > work_struct *work)
> > unsigned int fences = 0;
> > unsigned int i, j;
> >
> > + /* Nothing holding the reset semaphore waits for this work */
> > + down_read(&adev->reset_domain->sem);
> > +
> > for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
> > if (adev->jpeg.harvest_config & (1U << i))
> > continue;
> > @@ -129,6 +153,8 @@ static void amdgpu_jpeg_idle_work_handler(struct
> > work_struct *work)
> > mutex_unlock(&adev->jpeg.jpeg_pg_lock);
> > } else
> > schedule_delayed_work(&adev->jpeg.idle_work,
> > JPEG_IDLE_TIMEOUT);
> > +
> > + up_read(&adev->reset_domain->sem);
> > }
> >
> > void amdgpu_jpeg_ring_begin_use(struct amdgpu_ring *ring)
> > @@ -136,7 +162,7 @@ void amdgpu_jpeg_ring_begin_use(struct
> > amdgpu_ring *ring)
> > struct amdgpu_device *adev = ring->adev;
> >
> > if (!atomic_fetch_inc(&adev->jpeg.total_submission_cnt))
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_cancel_idle_work(adev);
> >
> > mutex_lock(&adev->jpeg.jpeg_pg_lock);
> > amdgpu_device_ip_set_powergating_state(adev,
> > AMD_IP_BLOCK_TYPE_JPEG,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
> > index 05d58e6bbfab..a473becb5def 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
> > @@ -156,6 +156,7 @@ struct amdgpu_jpeg {
> >
> > int amdgpu_jpeg_sw_init(struct amdgpu_device *adev);
> > int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev);
> > +int amdgpu_jpeg_early_fini(struct amdgpu_ip_block *ip_block);
> > int amdgpu_jpeg_suspend(struct amdgpu_device *adev);
> > int amdgpu_jpeg_resume(struct amdgpu_device *adev);
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> > index 34e1242d66ea..6c12d8aa3c76 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> > @@ -299,6 +299,26 @@ void amdgpu_vcn_sw_fini(struct amdgpu_device
> > *adev, int i)
> > mutex_destroy(&adev->vcn.inst[i].vcn1_jpeg1_workaround);
> > }
> >
> > +int amdgpu_vcn_early_fini(struct amdgpu_ip_block *ip_block)
> > +{
> > + struct amdgpu_device *adev = ip_block->adev;
> > + int i;
> > +
> > + /* Called on teardown even if sw_init never ran */
> > + if (!ip_block->status.sw)
> > + return 0;
> > +
> > + /* hw_fini may not wait while a peer in the reset domain resets */
> > + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
> > + if (adev->vcn.harvest_config & (1 << i))
> > + continue;
> > +
> > + cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum
> > vcn_ring_type type, uint32_t vcn_instance)
> > {
> > bool ret = false;
> > @@ -459,6 +479,15 @@ void amdgpu_vcn_put_profile(struct
> > amdgpu_device *adev)
> > mutex_unlock(&adev->vcn.workload_profile_mutex);
> > }
> >
> > +void amdgpu_vcn_cancel_idle_work(struct amdgpu_vcn_inst *vcn_inst)
> > +{
> > + /* The reset mustn't wait for the idle work, which waits for the
> > reset */
> > + if (amdgpu_in_reset(vcn_inst->adev))
> > + cancel_delayed_work(&vcn_inst->idle_work);
> > + else
> > + cancel_delayed_work_sync(&vcn_inst->idle_work);
> > +}
> > +
> > static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
> > {
> > struct amdgpu_vcn_inst *vcn_inst =
> > @@ -470,6 +499,9 @@ static void amdgpu_vcn_idle_work_handler(struct
> > work_struct *work)
> > if (adev->vcn.harvest_config & (1 << i))
> > return;
> >
> > + /* Nothing holding the reset semaphore waits for this work */
> > + down_read(&adev->reset_domain->sem);
> > +
> > for (j = 0; j < adev->vcn.inst[i].num_enc_rings; ++j)
> > fence[i] += amdgpu_fence_count_emitted(&vcn_inst-
> > >ring_enc[j]);
> >
> > @@ -499,6 +531,8 @@ static void amdgpu_vcn_idle_work_handler(struct
> > work_struct *work)
> > } else {
> > schedule_delayed_work(&vcn_inst->idle_work,
> > VCN_IDLE_TIMEOUT);
> > }
> > +
> > + up_read(&adev->reset_domain->sem);
> > }
> >
> > void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
> > @@ -507,7 +541,7 @@ void amdgpu_vcn_ring_begin_use(struct
> > amdgpu_ring *ring)
> > struct amdgpu_vcn_inst *vcn_inst = &adev->vcn.inst[ring->me];
> >
> > if (!atomic_fetch_inc(&vcn_inst->total_submission_cnt))
> > - cancel_delayed_work_sync(&vcn_inst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vcn_inst);
> >
> > mutex_lock(&vcn_inst->vcn_pg_lock);
> > vcn_inst->set_pg_state(vcn_inst, AMD_PG_STATE_UNGATE);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> > index bea95307fd42..509c83799a8a 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> > @@ -522,10 +522,12 @@ enum vcn_ring_type {
> > int amdgpu_vcn_early_init(struct amdgpu_device *adev, int i);
> > int amdgpu_vcn_sw_init(struct amdgpu_device *adev, int i);
> > void amdgpu_vcn_sw_fini(struct amdgpu_device *adev, int i);
> > +int amdgpu_vcn_early_fini(struct amdgpu_ip_block *ip_block);
> > int amdgpu_vcn_suspend(struct amdgpu_device *adev, int i);
> > int amdgpu_vcn_resume(struct amdgpu_device *adev, int i);
> > void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring);
> > void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring);
> > +void amdgpu_vcn_cancel_idle_work(struct amdgpu_vcn_inst *vcn_inst);
> >
> > bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev,
> > enum vcn_ring_type type, uint32_t
> > vcn_instance);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> > index f03c1a37c8dd..1b498190954d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> > @@ -166,7 +166,7 @@ static int jpeg_v2_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> >
> > r = amdgpu_ring_test_helper(ring);
> > if (r)
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -181,7 +181,7 @@ static int jpeg_v2_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > {
> > struct amdgpu_device *adev = ip_block->adev;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
> > RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
> > @@ -792,6 +792,7 @@ static const struct amd_ip_funcs jpeg_v2_0_ip_funcs
> > = {
> > .early_init = jpeg_v2_0_early_init,
> > .sw_init = jpeg_v2_0_sw_init,
> > .sw_fini = jpeg_v2_0_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v2_0_hw_init,
> > .hw_fini = jpeg_v2_0_hw_fini,
> > .suspend = jpeg_v2_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> > index 46293664fd28..80c79aeeb410 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> > @@ -227,7 +227,7 @@ static int jpeg_v2_5_hw_init(struct amdgpu_ip_block
> > *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -243,7 +243,7 @@ static int jpeg_v2_5_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > int i;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
> > if (adev->jpeg.harvest_config & (1 << i))
> > @@ -665,6 +665,7 @@ static const struct amd_ip_funcs jpeg_v2_5_ip_funcs
> > = {
> > .early_init = jpeg_v2_5_early_init,
> > .sw_init = jpeg_v2_5_sw_init,
> > .sw_fini = jpeg_v2_5_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v2_5_hw_init,
> > .hw_fini = jpeg_v2_5_hw_fini,
> > .suspend = jpeg_v2_5_suspend,
> > @@ -681,6 +682,7 @@ static const struct amd_ip_funcs jpeg_v2_6_ip_funcs
> > = {
> > .early_init = jpeg_v2_5_early_init,
> > .sw_init = jpeg_v2_5_sw_init,
> > .sw_fini = jpeg_v2_5_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v2_5_hw_init,
> > .hw_fini = jpeg_v2_5_hw_fini,
> > .suspend = jpeg_v2_5_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> > index 361d0f4b4bc7..3411a32d00ee 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> > @@ -181,7 +181,7 @@ static int jpeg_v3_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> >
> > r = amdgpu_ring_test_helper(ring);
> > if (r)
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -196,7 +196,7 @@ static int jpeg_v3_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > {
> > struct amdgpu_device *adev = ip_block->adev;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
> > RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
> > @@ -564,6 +564,7 @@ static const struct amd_ip_funcs jpeg_v3_0_ip_funcs
> > = {
> > .early_init = jpeg_v3_0_early_init,
> > .sw_init = jpeg_v3_0_sw_init,
> > .sw_fini = jpeg_v3_0_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v3_0_hw_init,
> > .hw_fini = jpeg_v3_0_hw_fini,
> > .suspend = jpeg_v3_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> > index 4e8eed2b62db..4a916cc2bd01 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> > @@ -210,7 +210,7 @@ static int jpeg_v4_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -225,7 +225,7 @@ static int jpeg_v4_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > {
> > struct amdgpu_device *adev = ip_block->adev;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > if (!amdgpu_sriov_vf(adev)) {
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
> > RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
> > @@ -748,6 +748,7 @@ static const struct amd_ip_funcs jpeg_v4_0_ip_funcs
> > = {
> > .early_init = jpeg_v4_0_early_init,
> > .sw_init = jpeg_v4_0_sw_init,
> > .sw_fini = jpeg_v4_0_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v4_0_hw_init,
> > .hw_fini = jpeg_v4_0_hw_fini,
> > .suspend = jpeg_v4_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
> > index 9f298c4ea8ff..6b62731495ab 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
> > @@ -443,7 +443,7 @@ static int jpeg_v4_0_3_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -459,7 +459,7 @@ static int jpeg_v4_0_3_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > int ret = 0;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
> > @@ -1227,6 +1227,7 @@ static const struct amd_ip_funcs
> > jpeg_v4_0_3_ip_funcs = {
> > .early_init = jpeg_v4_0_3_early_init,
> > .sw_init = jpeg_v4_0_3_sw_init,
> > .sw_fini = jpeg_v4_0_3_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v4_0_3_hw_init,
> > .hw_fini = jpeg_v4_0_3_hw_fini,
> > .suspend = jpeg_v4_0_3_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
> > index a1496412810c..109237055eba 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
> > @@ -238,7 +238,7 @@ static int jpeg_v4_0_5_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -254,7 +254,7 @@ static int jpeg_v4_0_5_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > int i;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
> > if (adev->jpeg.harvest_config & (1 << i))
> > @@ -807,6 +807,7 @@ static const struct amd_ip_funcs
> > jpeg_v4_0_5_ip_funcs = {
> > .early_init = jpeg_v4_0_5_early_init,
> > .sw_init = jpeg_v4_0_5_sw_init,
> > .sw_fini = jpeg_v4_0_5_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v4_0_5_hw_init,
> > .hw_fini = jpeg_v4_0_5_hw_fini,
> > .suspend = jpeg_v4_0_5_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
> > index 1a4594d5d952..c0bacaafdf7f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
> > @@ -178,7 +178,7 @@ static int jpeg_v5_0_0_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -193,7 +193,7 @@ static int jpeg_v5_0_0_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > {
> > struct amdgpu_device *adev = ip_block->adev;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
> > RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
> > @@ -683,6 +683,7 @@ static const struct amd_ip_funcs
> > jpeg_v5_0_0_ip_funcs = {
> > .early_init = jpeg_v5_0_0_early_init,
> > .sw_init = jpeg_v5_0_0_sw_init,
> > .sw_fini = jpeg_v5_0_0_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v5_0_0_hw_init,
> > .hw_fini = jpeg_v5_0_0_hw_fini,
> > .suspend = jpeg_v5_0_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
> > index efdc537ec81e..9ae23235d16c 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
> > @@ -314,7 +314,7 @@ static int jpeg_v5_0_1_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -330,7 +330,7 @@ static int jpeg_v5_0_1_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > int ret = 0;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
> > @@ -887,6 +887,7 @@ static const struct amd_ip_funcs
> > jpeg_v5_0_1_ip_funcs = {
> > .late_init = NULL,
> > .sw_init = jpeg_v5_0_1_sw_init,
> > .sw_fini = jpeg_v5_0_1_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v5_0_1_hw_init,
> > .hw_fini = jpeg_v5_0_1_hw_fini,
> > .suspend = jpeg_v5_0_1_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c
> > index eb3dc9558e0d..0fc58d25abe1 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c
> > @@ -287,7 +287,7 @@ static int jpeg_v5_0_2_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -303,7 +303,7 @@ static int jpeg_v5_0_2_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > int ret = 0;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
> > @@ -871,6 +871,7 @@ static const struct amd_ip_funcs
> > jpeg_v5_0_2_ip_funcs = {
> > .late_init = NULL,
> > .sw_init = jpeg_v5_0_2_sw_init,
> > .sw_fini = jpeg_v5_0_2_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v5_0_2_hw_init,
> > .hw_fini = jpeg_v5_0_2_hw_fini,
> > .suspend = jpeg_v5_0_2_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c
> > b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c
> > index 0cbb2b8a7e78..d5bc6820ad8d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c
> > @@ -161,7 +161,7 @@ static int jpeg_v5_3_0_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> > return r;
> > }
> >
> > @@ -176,7 +176,7 @@ static int jpeg_v5_3_0_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > {
> > struct amdgpu_device *adev = ip_block->adev;
> >
> > - cancel_delayed_work_sync(&adev->jpeg.idle_work);
> > + amdgpu_jpeg_suspend(adev);
> >
> > if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
> > RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS))
> > @@ -671,6 +671,7 @@ static const struct amd_ip_funcs
> > jpeg_v5_3_0_ip_funcs = {
> > .early_init = jpeg_v5_3_0_early_init,
> > .sw_init = jpeg_v5_3_0_sw_init,
> > .sw_fini = jpeg_v5_3_0_sw_fini,
> > + .early_fini = amdgpu_jpeg_early_fini,
> > .hw_init = jpeg_v5_3_0_hw_init,
> > .hw_fini = jpeg_v5_3_0_hw_fini,
> > .suspend = jpeg_v5_3_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> > index b3e63d6e79a8..897310d04f83 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> > @@ -150,8 +150,8 @@ static int vcn_v1_0_sw_init(struct amdgpu_ip_block
> > *ip_block)
> > if (r)
> > return r;
> >
> > - /* Override the work func */
> > - adev->vcn.inst[0].idle_work.work.func =
> > vcn_v1_0_idle_work_handler;
> > + /* Own lockdep class, this work is still cancelled synchronously */
> > + INIT_DELAYED_WORK(&adev->vcn.inst[0].idle_work,
> > vcn_v1_0_idle_work_handler);
> >
> > amdgpu_vcn_setup_ucode(adev, 0);
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> > index 12ac20484396..706089744803 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> > @@ -310,7 +310,7 @@ static int vcn_v2_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> > return 0;
> >
> > error:
> > - cancel_delayed_work_sync(&adev->vcn.inst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(adev->vcn.inst);
> > return r;
> > }
> >
> > @@ -326,7 +326,7 @@ static int vcn_v2_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > struct amdgpu_device *adev = ip_block->adev;
> > struct amdgpu_vcn_inst *vinst = adev->vcn.inst;
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
> > (vinst->cur_state != AMD_PG_STATE_GATE &&
> > @@ -2103,6 +2103,7 @@ static const struct amd_ip_funcs
> > vcn_v2_0_ip_funcs = {
> > .early_init = vcn_v2_0_early_init,
> > .sw_init = vcn_v2_0_sw_init,
> > .sw_fini = vcn_v2_0_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v2_0_hw_init,
> > .hw_fini = vcn_v2_0_hw_fini,
> > .suspend = vcn_v2_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> > index 2b2abe689508..c3f2265f50fc 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> > @@ -304,8 +304,8 @@ static int vcn_v2_5_sw_init(struct amdgpu_ip_block
> > *ip_block)
> > if (r)
> > return r;
> >
> > - /* Override the work func */
> > - adev->vcn.inst[j].idle_work.work.func =
> > vcn_v2_5_idle_work_handler;
> > + /* Own lockdep class, this work is still cancelled
> > synchronously
> > */
> > + INIT_DELAYED_WORK(&adev->vcn.inst[j].idle_work,
> > vcn_v2_5_idle_work_handler);
> >
> > amdgpu_vcn_setup_ucode(adev, j);
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> > index 6543f21daa1e..8f256d962ce5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> > @@ -433,7 +433,7 @@ static int vcn_v3_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -457,7 +457,7 @@ static int vcn_v3_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > if (adev->vcn.harvest_config & (1 << i))
> > continue;
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
> > ||
> > @@ -2366,6 +2366,7 @@ static const struct amd_ip_funcs
> > vcn_v3_0_ip_funcs = {
> > .early_init = vcn_v3_0_early_init,
> > .sw_init = vcn_v3_0_sw_init,
> > .sw_fini = vcn_v3_0_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v3_0_hw_init,
> > .hw_fini = vcn_v3_0_hw_fini,
> > .suspend = vcn_v3_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> > index 8b5646297c2e..b68746b37a15 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> > @@ -358,7 +358,7 @@ static int vcn_v4_0_hw_init(struct amdgpu_ip_block
> > *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -382,7 +382,7 @@ static int vcn_v4_0_hw_fini(struct amdgpu_ip_block
> > *ip_block)
> > if (adev->vcn.harvest_config & (1 << i))
> > continue;
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
> > ||
> > @@ -2287,6 +2287,7 @@ static const struct amd_ip_funcs
> > vcn_v4_0_ip_funcs = {
> > .early_init = vcn_v4_0_early_init,
> > .sw_init = vcn_v4_0_sw_init,
> > .sw_fini = vcn_v4_0_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v4_0_hw_init,
> > .hw_fini = vcn_v4_0_hw_fini,
> > .suspend = vcn_v4_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> > index 0c58ca25d7b5..a1bfcece38fb 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> > @@ -404,7 +404,7 @@ static int vcn_v4_0_3_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -425,7 +425,7 @@ static int vcn_v4_0_3_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
> > struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if (vinst->cur_state != AMD_PG_STATE_GATE)
> > vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
> > @@ -2035,6 +2035,7 @@ static const struct amd_ip_funcs
> > vcn_v4_0_3_ip_funcs = {
> > .late_init = vcn_v4_0_3_late_init,
> > .sw_init = vcn_v4_0_3_sw_init,
> > .sw_fini = vcn_v4_0_3_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v4_0_3_hw_init,
> > .hw_fini = vcn_v4_0_3_hw_fini,
> > .suspend = vcn_v4_0_3_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> > index a6eaa57ec2ee..fb5336f46ac9 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> > @@ -311,7 +311,7 @@ static int vcn_v4_0_5_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -335,7 +335,7 @@ static int vcn_v4_0_5_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > if (adev->vcn.harvest_config & (1 << i))
> > continue;
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
> > ||
> > @@ -1690,6 +1690,7 @@ static const struct amd_ip_funcs
> > vcn_v4_0_5_ip_funcs = {
> > .early_init = vcn_v4_0_5_early_init,
> > .sw_init = vcn_v4_0_5_sw_init,
> > .sw_fini = vcn_v4_0_5_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v4_0_5_hw_init,
> > .hw_fini = vcn_v4_0_5_hw_fini,
> > .suspend = vcn_v4_0_5_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> > index 055729a42094..b18c61e6d099 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> > @@ -275,7 +275,7 @@ static int vcn_v5_0_0_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -299,7 +299,7 @@ static int vcn_v5_0_0_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > if (adev->vcn.harvest_config & (1 << i))
> > continue;
> >
> > - cancel_delayed_work_sync(&vinst->idle_work);
> > + amdgpu_vcn_cancel_idle_work(vinst);
> >
> > if (!amdgpu_sriov_vf(adev)) {
> > if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
> > ||
> > @@ -1476,6 +1476,7 @@ static const struct amd_ip_funcs
> > vcn_v5_0_0_ip_funcs = {
> > .early_init = vcn_v5_0_0_early_init,
> > .sw_init = vcn_v5_0_0_sw_init,
> > .sw_fini = vcn_v5_0_0_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v5_0_0_hw_init,
> > .hw_fini = vcn_v5_0_0_hw_fini,
> > .suspend = vcn_v5_0_0_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> > index 55a4b2f9463f..a5d3ee06fced 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> > @@ -351,7 +351,7 @@ static int vcn_v5_0_1_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -372,7 +372,7 @@ static int vcn_v5_0_1_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
> > struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
> >
> > - cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > if (vinst->cur_state != AMD_PG_STATE_GATE)
> > vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
> > }
> > @@ -1660,6 +1660,7 @@ static const struct amd_ip_funcs
> > vcn_v5_0_1_ip_funcs = {
> > .late_init = vcn_v5_0_1_late_init,
> > .sw_init = vcn_v5_0_1_sw_init,
> > .sw_fini = vcn_v5_0_1_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v5_0_1_hw_init,
> > .hw_fini = vcn_v5_0_1_hw_fini,
> > .suspend = vcn_v5_0_1_suspend,
> > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
> > b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
> > index ea6cdbcb6352..1b7897bb9953 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
> > @@ -266,7 +266,7 @@ static int vcn_v5_0_2_hw_init(struct
> > amdgpu_ip_block *ip_block)
> > error:
> > while (i >= 0) {
> > if (!(adev->vcn.harvest_config & (1 << i)))
> > - cancel_delayed_work_sync(&adev-
> > >vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > i--;
> > }
> > return r;
> > @@ -287,7 +287,7 @@ static int vcn_v5_0_2_hw_fini(struct
> > amdgpu_ip_block *ip_block)
> > for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
> > struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
> >
> > - cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work);
> > + amdgpu_vcn_cancel_idle_work(&adev->vcn.inst[i]);
> > if (vinst->cur_state != AMD_PG_STATE_GATE)
> > vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
> > }
> > @@ -1451,6 +1451,7 @@ static const struct amd_ip_funcs
> > vcn_v5_0_2_ip_funcs = {
> > .late_init = NULL,
> > .sw_init = vcn_v5_0_2_sw_init,
> > .sw_fini = vcn_v5_0_2_sw_fini,
> > + .early_fini = amdgpu_vcn_early_fini,
> > .hw_init = vcn_v5_0_2_hw_init,
> > .hw_fini = vcn_v5_0_2_hw_fini,
> > .suspend = vcn_v5_0_2_suspend,
> > --
> > 2.34.1
>