From patchwork Thu Oct 5 06:11:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 9986459 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AA243602B8 for ; Thu, 5 Oct 2017 06:11:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9958B28757 for ; Thu, 5 Oct 2017 06:11:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BB6528B96; Thu, 5 Oct 2017 06:11:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5579428757 for ; Thu, 5 Oct 2017 06:11:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751116AbdJEGLo (ORCPT ); Thu, 5 Oct 2017 02:11:44 -0400 Received: from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:44778 "EHLO hillosipuli.retiisi.org.uk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750824AbdJEGLn (ORCPT ); Thu, 5 Oct 2017 02:11:43 -0400 Received: from valkosipuli.localdomain (valkosipuli.retiisi.org.uk [IPv6:2001:1bc8:1a6:d3d5::80:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by hillosipuli.retiisi.org.uk (Postfix) with ESMTPS id CA97C600D8; Thu, 5 Oct 2017 09:11:40 +0300 (EEST) Received: from sakke by valkosipuli.localdomain with local (Exim 4.89) (envelope-from ) id 1dzzNk-0000l1-1w; Thu, 05 Oct 2017 09:11:40 +0300 Date: Thu, 5 Oct 2017 09:11:39 +0300 From: Sakari Ailus To: Sakari Ailus Cc: linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, pavel@ucw.cz, sre@kernel.org, devicetree@vger.kernel.org, linux-acpi@vger.kernel.org, marc.herbert@intel.com, hyungwoo.yang@intel.com, rajmohan.mani@intel.com, yong.zhi@intel.com Subject: Re: [PATCH v15 00/32] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS Message-ID: <20171005061139.cqrauwjjhy4pwvy6@valkosipuli.retiisi.org.uk> References: <20171004215051.13385-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20171004215051.13385-1-sakari.ailus@linux.intel.com> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, Oct 05, 2017 at 12:50:19AM +0300, Sakari Ailus wrote: > Hi folks, > > I've dropped the full set from devicetree and linux-acpi lists; > let me know if you want it back. The entire set is posted to > linux-media list. Here's the diff between v14 and v15. The patches can be found here, with the dependencies: diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 5aae5cb38b81..ae026eee3d03 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -248,18 +248,20 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, list_move(&sd->async_list, ¬ifier->done); /* - * See if the sub-device has a notifier. If it does, proceed - * with checking for its async sub-devices. + * See if the sub-device has a notifier. If not, return here. */ subdev_notifier = v4l2_async_find_subdev_notifier(sd); - if (subdev_notifier && !subdev_notifier->parent) { - subdev_notifier->parent = notifier; - ret = v4l2_async_notifier_try_all_subdevs(subdev_notifier); - if (ret) - return ret; - } + if (!subdev_notifier || subdev_notifier->parent) + return 0; - return 0; + /* + * Proceed with checking for the sub-device notifier's async + * sub-devices, and return the result. The error will be handled by the + * caller. + */ + subdev_notifier->parent = notifier; + + return v4l2_async_notifier_try_all_subdevs(subdev_notifier); } /* Test all async sub-devices in a notifier for a match. */ @@ -304,7 +306,28 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd) /* Subdevice driver will reprobe and put the subdev back onto the list */ list_del_init(&sd->async_list); sd->asd = NULL; - sd->dev = NULL; +} + +/* Unbind all sub-devices in the notifier tree. */ +static void v4l2_async_notifier_unbind_all_subdevs( + struct v4l2_async_notifier *notifier) +{ + struct v4l2_subdev *sd, *tmp; + + 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) + v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); + + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + list_move(&sd->async_list, &subdev_list); + } + + notifier->parent = NULL; } /* See if an fwnode can be found in a notifier's lists. */ @@ -412,9 +435,11 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) ret = v4l2_async_notifier_try_all_subdevs(notifier); if (ret) - goto out_unlock; + goto err_unbind; ret = v4l2_async_notifier_try_complete(notifier); + if (ret) + goto err_unbind; /* Keep also completed notifiers on the list */ list_add(¬ifier->list, ¬ifier_list); @@ -422,69 +447,74 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) out_unlock: mutex_unlock(&list_lock); + return 0; + +err_unbind: + /* + * On failure, unbind all sub-devices registered through this notifier. + */ + v4l2_async_notifier_unbind_all_subdevs(notifier); + + mutex_unlock(&list_lock); + return ret; } int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, struct v4l2_async_notifier *notifier) { + int ret; + if (WARN_ON(!v4l2_dev || notifier->sd)) return -EINVAL; notifier->v4l2_dev = v4l2_dev; - return __v4l2_async_notifier_register(notifier); + ret = __v4l2_async_notifier_register(notifier); + if (ret) + notifier->v4l2_dev = NULL; + + return ret; } EXPORT_SYMBOL(v4l2_async_notifier_register); int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, struct v4l2_async_notifier *notifier) { + int ret; + if (WARN_ON(!sd || notifier->v4l2_dev)) return -EINVAL; notifier->sd = sd; - return __v4l2_async_notifier_register(notifier); + ret = __v4l2_async_notifier_register(notifier); + if (ret) + notifier->sd = NULL; + + return ret; } EXPORT_SYMBOL(v4l2_async_subdev_notifier_register); -/* Unbind all sub-devices in the notifier tree. */ -static void v4l2_async_notifier_unbind_all_subdevs( +static void __v4l2_async_notifier_unregister( struct v4l2_async_notifier *notifier) { - struct v4l2_subdev *sd, *tmp; - - 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) - v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); - - v4l2_async_cleanup(sd); + if (!notifier || (!notifier->v4l2_dev && !notifier->sd)) + return; - v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + v4l2_async_notifier_unbind_all_subdevs(notifier); - list_move(&sd->async_list, &subdev_list); - } + notifier->sd = NULL; + notifier->v4l2_dev = NULL; - notifier->parent = NULL; + list_del(¬ifier->list); } void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) { - if (!notifier->v4l2_dev && !notifier->sd) - return; - mutex_lock(&list_lock); - v4l2_async_notifier_unbind_all_subdevs(notifier); - - notifier->sd = NULL; - notifier->v4l2_dev = NULL; - - list_del(¬ifier->list); + __v4l2_async_notifier_unregister(notifier); mutex_unlock(&list_lock); } @@ -522,7 +552,9 @@ EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup); int v4l2_async_register_subdev(struct v4l2_subdev *sd) { + struct v4l2_async_notifier *subdev_notifier; struct v4l2_async_notifier *notifier; + int ret; /* * No reference taken. The reference is held by the device @@ -549,47 +581,64 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) if (!asd) continue; - ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd); + ret = v4l2_async_match_notify(notifier, notifier->v4l2_dev, sd, + asd); + if (ret) + goto err_unbind; - if (!ret) - ret = v4l2_async_notifier_try_complete(notifier); + ret = v4l2_async_notifier_try_complete(notifier); + if (ret) + goto err_unbind; - mutex_unlock(&list_lock); - return ret; + goto out_unlock; } /* None matched, wait for hot-plugging */ list_add(&sd->async_list, &subdev_list); +out_unlock: mutex_unlock(&list_lock); return 0; + +err_unbind: + /* + * Complete failed. Unbind the sub-devices bound through registering + * this async sub-device. + */ + subdev_notifier = v4l2_async_find_subdev_notifier(sd); + if (subdev_notifier) + v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); + + if (sd->asd) + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + mutex_unlock(&list_lock); + + return ret; } EXPORT_SYMBOL(v4l2_async_register_subdev); void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) { - struct v4l2_async_notifier *notifier = sd->notifier; + mutex_lock(&list_lock); - if (sd->subdev_notifier) - v4l2_async_notifier_unregister(sd->subdev_notifier); + __v4l2_async_notifier_unregister(sd->subdev_notifier); v4l2_async_notifier_cleanup(sd->subdev_notifier); kfree(sd->subdev_notifier); + sd->subdev_notifier = NULL; - if (!sd->asd) { - if (!list_empty(&sd->async_list)) - v4l2_async_cleanup(sd); - return; - } + if (sd->asd) { + struct v4l2_async_notifier *notifier = sd->notifier; - mutex_lock(&list_lock); + list_add(&sd->asd->list, ¬ifier->waiting); - list_add(&sd->asd->list, ¬ifier->waiting); + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + } v4l2_async_cleanup(sd); - v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); - mutex_unlock(&list_lock); } EXPORT_SYMBOL(v4l2_async_unregister_subdev); diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 74f2ea27d117..65f87e80081a 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -201,5 +201,4 @@ int __must_check v4l2_async_register_subdev_sensor_common( * @sd: pointer to &struct v4l2_subdev */ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); - #endif diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 834e74246412..43fd1a278bcc 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -137,7 +137,7 @@ struct v4l2_fwnode_link { int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); -/* +/** * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by * v4l2_fwnode_endpoint_alloc_parse() * @vep - the V4L2 fwnode the resources of which are to be released