author | apollo.ling <apollo.ling@amlogic.com> | 2020-03-25 08:09:54 (GMT) |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2020-10-19 11:35:32 (GMT) |
commit | a470783d19c78ec2dc6b46cfa22263a3f4ecb6ba (patch) | |
tree | 45ba9456c28d80c73e6167ffbf66a36440caa60a | |
parent | 66932c3654f449f388d263a5fc774b4dc694edcb (diff) | |
download | media_modules-a470783d19c78ec2dc6b46cfa22263a3f4ecb6ba.zip media_modules-a470783d19c78ec2dc6b46cfa22263a3f4ecb6ba.tar.gz media_modules-a470783d19c78ec2dc6b46cfa22263a3f4ecb6ba.tar.bz2 |
vdec: remove vdec from connected_vdec_list before release it [1/1]
PD#TV-16434
PD#GH-722
BUG=170591585
Problem:
When timeout happens both in vdec_disconnect and platform_device_unregister,
we release the vdec, but the vdec still in connected_vdec_list
Solution:
remove vdec from connected_vdec_list before release it
Verify:
sm1
Change-Id: I6d732213a4929b2ba718d92bfb64a3e3d154551b
Signed-off-by: apollo.ling <apollo.ling@amlogic.com>
Reviewed-on: https://eureka-partner-review.googlesource.com/c/amlogic/media_modules/+/176144
Reviewed-by: Ben Cheng <bccheng@google.com>
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index 41e84ba..d1a66fe 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -2363,6 +2363,34 @@ error: } EXPORT_SYMBOL(vdec_init); +/* + *Remove the vdec after timeout happens both in vdec_disconnect + *and platform_device_unregister. Then after, we can release the vdec. + */ +static void vdec_connect_list_force_clear(struct vdec_core_s *core, struct vdec_s *v_ref) +{ + struct vdec_s *vdec, *tmp; + unsigned long flags; + + flags = vdec_core_lock(core); + + list_for_each_entry_safe(vdec, tmp, + &core->connected_vdec_list, list) { + if ((vdec->status == VDEC_STATUS_DISCONNECTED) && + (vdec == v_ref)) { + pr_err("%s, vdec = %p, active vdec = %p\n", + __func__, vdec, core->active_vdec); + if (core->active_vdec == v_ref) + core->active_vdec = NULL; + if (core->last_vdec == v_ref) + core->last_vdec = NULL; + list_del(&vdec->list); + } + } + + vdec_core_unlock(core, flags); +} + /* vdec_create/init/release/destroy are applied to both dual running decoders */ void vdec_release(struct vdec_s *vdec) @@ -2415,6 +2443,8 @@ void vdec_release(struct vdec_s *vdec) if (atomic_read(&vdec_core->vdec_nr) == 1) vdec_disable_DMC(vdec); platform_device_unregister(vdec->dev); + /*Check if the vdec still in connected list, if yes, delete it*/ + vdec_connect_list_force_clear(vdec_core, vdec); pr_debug("vdec_release instance %p, total %d\n", vdec, atomic_read(&vdec_core->vdec_nr)); if (vdec->use_vfm_path) { |