summaryrefslogtreecommitdiff
authorapollo.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)
commita470783d19c78ec2dc6b46cfa22263a3f4ecb6ba (patch)
tree45ba9456c28d80c73e6167ffbf66a36440caa60a
parent66932c3654f449f388d263a5fc774b4dc694edcb (diff)
downloadmedia_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>
Diffstat
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c30
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) {