From a2d74ca47bd4fdf9b5cdb9f3346de246a4f118a0 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 17 Aug 2021 11:01:16 +0800 Subject: [PATCH] media: v4l: add API to clear unready device Change-Id: I497719e6e8f2ef25a9d6402c16733bf4318d06d7 Signed-off-by: Cai YiWei --- drivers/media/v4l2-core/v4l2-async.c | 54 ++++++++++++++++++++++++++++ include/media/v4l2-async.h | 15 ++++++++ 2 files changed, 69 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index e3ab003a6c85..f9ba900e2e88 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -555,6 +555,60 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, } EXPORT_SYMBOL(v4l2_async_notifier_register); +#if IS_ENABLED(CONFIG_NO_GKI) +static int __v4l2_async_notifier_clr_unready_dev( + struct v4l2_async_notifier *notifier) +{ + struct v4l2_subdev *sd, *tmp; + int clr_num = 0; + + list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) { + struct v4l2_async_notifier *subdev_notifier = + v4l2_async_find_subdev_notifier(sd); + + if (subdev_notifier) + clr_num += __v4l2_async_notifier_clr_unready_dev( + subdev_notifier); + } + + list_for_each_entry_safe(sd, tmp, ¬ifier->waiting, async_list) { + list_del_init(&sd->async_list); + sd->asd = NULL; + sd->dev = NULL; + clr_num++; + } + + return clr_num; +} + +int v4l2_async_notifier_clr_unready_dev(struct v4l2_async_notifier *notifier) +{ + int ret = 0; + int clr_num = 0; + + mutex_lock(&list_lock); + + while (notifier->parent) + notifier = notifier->parent; + + if (!notifier->v4l2_dev) + goto out; + + clr_num = __v4l2_async_notifier_clr_unready_dev(notifier); + dev_info(notifier->v4l2_dev->dev, + "clear unready subdev num: %d\n", clr_num); + + if (clr_num > 0) + ret = v4l2_async_notifier_try_complete(notifier); + +out: + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(v4l2_async_notifier_clr_unready_dev); +#endif + int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, struct v4l2_async_notifier *notifier) { diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index d6e31234826f..30e9be7db676 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -265,6 +265,21 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, struct v4l2_async_notifier *notifier); +/** + * v4l2_async_notifier_clr_unready_dev - remove unready subdevice + * + * @notifier: pointer to &struct v4l2_async_notifier + */ +#if IS_ENABLED(CONFIG_NO_GKI) +int v4l2_async_notifier_clr_unready_dev(struct v4l2_async_notifier *notifier); +#else +static inline int +v4l2_async_notifier_clr_unready_dev(struct v4l2_async_notifier *notifier) +{ + return 0; +} +#endif + /** * v4l2_async_notifier_unregister - unregisters a subdevice * asynchronous notifier