All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
Cc: Hans Verkuil <hverkuil@xs4all.nl>,
	linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	tomoharu.fukawa.eb@renesas.com,
	Kieran Bingham <kieran.bingham@ideasonboard.com>
Subject: Re: [PATCH v10 22/30] rcar-vin: add group allocator functions
Date: Tue, 13 Feb 2018 22:09:56 +0200	[thread overview]
Message-ID: <1907646.jK4vy9bKSB@avalon> (raw)
In-Reply-To: <20180129163435.24936-23-niklas.soderlund+renesas@ragnatech.se>

Hi Niklas,

Thank you for the patch.

On Monday, 29 January 2018 18:34:27 EET Niklas Söderlund wrote:
> In media controller mode all VIN instances needs to be part of the same
> media graph. There is also a need for each VIN instance to know about
> and in some cases be able to communicate with other VIN instances.
> 
> Add an allocator framework where the first VIN instance to be probed
> creates a shared data structure and registers a media device.
> Consecutive VINs insert themself into the global group.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 177 ++++++++++++++++++++++++-
>  drivers/media/platform/rcar-vin/rcar-vin.h  |  31 +++++
>  2 files changed, 206 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c
> b/drivers/media/platform/rcar-vin/rcar-core.c index
> 0c6960756c33f86c..4a64df5019ce45f7 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -20,12 +20,177 @@
>  #include <linux/of_graph.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/slab.h>
> 
>  #include <media/v4l2-async.h>
>  #include <media/v4l2-fwnode.h>
> 
>  #include "rcar-vin.h"
> 
> +/* ------------------------------------------------------------------------
> + * Gen3 CSI2 Group Allocator
> + */
> +
> +/* FIXME:  This should if we find a system that supports more
> + * then one group for the whole system be replaced with a linked

s/then/than/

> + * list of groups. And eventually all of this should be replaced
> + * with a global device allocator API.
> + *
> + * But for now this works as on all supported systems there will
> + * be only one group for all instances.
> + */
> +
> +static DEFINE_MUTEX(rvin_group_lock);
> +static struct rvin_group *rvin_group_data;
> +
> +static void rvin_group_cleanup(struct rvin_group *group)
> +{
> +	media_device_unregister(&group->mdev);
> +	media_device_cleanup(&group->mdev);
> +	mutex_destroy(&group->lock);
> +}
> +
> +static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
> +{
> +	struct media_device *mdev = &group->mdev;
> +	const struct of_device_id *match;
> +	struct device_node *np;
> +	int ret;
> +
> +	mutex_init(&group->lock);
> +
> +	/* Count number of VINs in the system */
> +	group->count = 0;
> +	for_each_matching_node(np, vin->dev->driver->of_match_table)
> +		if (of_device_is_available(np))
> +			group->count++;
> +
> +	vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
> +
> +	mdev->dev = vin->dev;
> +
> +	match = of_match_node(vin->dev->driver->of_match_table,
> +			      vin->dev->of_node);
> +
> +	strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
> +	strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
> +	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
> +		 dev_name(mdev->dev));
> +
> +	media_device_init(mdev);
> +
> +	ret = media_device_register(&group->mdev);
> +	if (ret)
> +		rvin_group_cleanup(group);
> +
> +	return ret;
> +}
> +
> +static void rvin_group_release(struct kref *kref)
> +{
> +	struct rvin_group *group =
> +		container_of(kref, struct rvin_group, refcount);
> +
> +	mutex_lock(&rvin_group_lock);
> +
> +	rvin_group_data = NULL;
> +
> +	rvin_group_cleanup(group);
> +
> +	kfree(group);
> +
> +	mutex_unlock(&rvin_group_lock);
> +}
> +
> +static int rvin_group_get(struct rvin_dev *vin)
> +{
> +	struct rvin_group *group;
> +	u32 id;
> +	int ret;
> +
> +	/* Make sure VIN id is present and sane */
> +	ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
> +	if (ret) {
> +		vin_err(vin, "%pOF: No renesas,id property found\n",
> +			vin->dev->of_node);
> +		return -EINVAL;
> +	}
> +
> +	if (id >= RCAR_VIN_NUM) {
> +		vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
> +			vin->dev->of_node, id);
> +		return -EINVAL;
> +	}

I'd move this out of this function to an OF parsing function, but we don't 
have one yet. Something to keep in mind for later.

> +	/* Join or create a VIN group */
> +	mutex_lock(&rvin_group_lock);
> +	if (rvin_group_data) {
> +		group = rvin_group_data;
> +		kref_get(&group->refcount);
> +	} else {
> +		group = kzalloc(sizeof(*group), GFP_KERNEL);
> +		if (!group) {
> +			ret = -ENOMEM;
> +			goto err_group;
> +		}
> +
> +		ret = rvin_group_init(group, vin);
> +		if (ret) {
> +			kfree(group);
> +			vin_err(vin, "Failed to initialize group\n");
> +			goto err_group;
> +		}
> +
> +		kref_init(&group->refcount);
> +
> +		rvin_group_data = group;
> +	}
> +	mutex_unlock(&rvin_group_lock);
> +
> +	/* Add VIN to group */
> +	mutex_lock(&group->lock);
> +
> +	if (group->vin[id]) {
> +		vin_err(vin, "Duplicate renesas,id property value %u\n", id);
> +		ret = -EINVAL;
> +		goto err_vin;
> +	}
> +
> +	group->vin[id] = vin;
> +
> +	vin->id = id;
> +	vin->group = group;
> +	vin->v4l2_dev.mdev = &group->mdev;
> +
> +	mutex_unlock(&group->lock);
> +
> +	return 0;
> +err_group:
> +	mutex_unlock(&rvin_group_lock);
> +	return ret;
> +err_vin:
> +	mutex_unlock(&group->lock);
> +	kref_put(&group->refcount, rvin_group_release);
> +	return ret;

This error handling path is used from a single location, you can inline it.

> +}
> +
> +static void rvin_group_put(struct rvin_dev *vin)
> +{
> +	mutex_lock(&vin->group->lock);
> +
> +	vin->group = NULL;
> +	vin->v4l2_dev.mdev = NULL;
> +
> +	if (WARN_ON(vin->group->vin[vin->id] != vin))
> +		goto out;
> +
> +	vin->group->vin[vin->id] = NULL;
> +out:
> +	mutex_unlock(&vin->group->lock);
> +
> +	kref_put(&vin->group->refcount, rvin_group_release);
> +}
> +
>  /* ------------------------------------------------------------------------
>   * Async notifier
>   */
> @@ -243,12 +408,18 @@ static int rvin_digital_graph_init(struct rvin_dev
> *vin)
> 
>  static int rvin_mc_init(struct rvin_dev *vin)
>  {
> +	int ret;
> +
>  	/* All our sources are CSI-2 */
>  	vin->mbus_cfg.type = V4L2_MBUS_CSI2;
>  	vin->mbus_cfg.flags = 0;
> 
>  	vin->pad.flags = MEDIA_PAD_FL_SINK;
> -	return media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
> +	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
> +	if (ret)
> +		return ret;
> +
> +	return rvin_group_get(vin);
>  }
> 
>  /* ------------------------------------------------------------------------
> @@ -368,7 +539,9 @@ static int rcar_vin_remove(struct platform_device
> *pdev) v4l2_async_notifier_unregister(&vin->notifier);
>  	v4l2_async_notifier_cleanup(&vin->notifier);
> 
> -	if (!vin->info->use_mc)
> +	if (vin->info->use_mc)
> +		rvin_group_put(vin);
> +	else
>  		v4l2_ctrl_handler_free(&vin->ctrl_handler);
> 
>  	rvin_dma_unregister(vin);
> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h
> b/drivers/media/platform/rcar-vin/rcar-vin.h index
> 4caef7193db09c5b..903d8fb8426a7860 100644
> --- a/drivers/media/platform/rcar-vin/rcar-vin.h
> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h
> @@ -17,6 +17,8 @@
>  #ifndef __RCAR_VIN__
>  #define __RCAR_VIN__
> 
> +#include <linux/kref.h>
> +
>  #include <media/v4l2-async.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-dev.h>
> @@ -29,6 +31,11 @@
>  /* Address alignment mask for HW buffers */
>  #define HW_BUFFER_MASK 0x7f
> 
> +/* Max number on VIN instances that can be in a system */
> +#define RCAR_VIN_NUM 8
> +
> +struct rvin_group;
> +
>  enum model_id {
>  	RCAR_H1,
>  	RCAR_M1,
> @@ -101,6 +108,8 @@ struct rvin_info {
>   * @notifier:		V4L2 asynchronous subdevs notifier
>   * @digital:		entity in the DT for local digital subdevice
>   *
> + * @group:		Gen3 CSI group
> + * @id:			Gen3 group id for this VIN
>   * @pad:		media pad for the video device entity
>   *
>   * @lock:		protects @queue
> @@ -132,6 +141,8 @@ struct rvin_dev {
>  	struct v4l2_async_notifier notifier;
>  	struct rvin_graph_entity *digital;
> 
> +	struct rvin_group *group;
> +	unsigned char id;

You can use an unsigned int, the compiler would pad the field anyway.

>  	struct media_pad pad;
> 
>  	struct mutex lock;
> @@ -160,6 +171,26 @@ struct rvin_dev {
>  #define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
>  #define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
> 
> +/**
> + * struct rvin_group - VIN CSI2 group information
> + * @refcount:		number of VIN instances using the group
> + *
> + * @mdev:		media device which represents the group
> + *
> + * @lock:		protects the count and vin members
> + * @count:		number of enabled VIN instances found in DT
> + * @vin:		VIN instances which are part of the group
> + */
> +struct rvin_group {
> +	struct kref refcount;
> +
> +	struct media_device mdev;
> +
> +	struct mutex lock;
> +	unsigned int count;
> +	struct rvin_dev *vin[RCAR_VIN_NUM];
> +};
> +
>  int rvin_dma_register(struct rvin_dev *vin, int irq);
>  void rvin_dma_unregister(struct rvin_dev *vin);

With these small issues fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

-- 
Regards,

Laurent Pinchart

  reply	other threads:[~2018-02-13 20:09 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-29 16:34 [PATCH v10 00/30] rcar-vin: Add Gen3 with media controller Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 01/30] rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
2018-02-13 15:24   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 02/30] rcar-vin: rename poorly named initialize and cleanup functions Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 03/30] rcar-vin: unregister video device on driver removal Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 04/30] rcar-vin: move subdevice handling to async callbacks Niklas Söderlund
2018-02-13 15:47   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 05/30] rcar-vin: move model information to own struct Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 06/30] rcar-vin: move max width and height information to chip information Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 07/30] rcar-vin: move functions regarding scaling Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 08/30] rcar-vin: all Gen2 boards can scale simplify logic Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 09/30] rcar-vin: read subdevice format for crop only when needed Niklas Söderlund
2018-02-13 16:14   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 10/30] rcar-vin: fix handling of single field frames (top, bottom and alternate fields) Niklas Söderlund
2018-02-13 16:26   ` Laurent Pinchart
2018-02-13 16:47     ` Niklas Söderlund
2018-02-13 16:47       ` Niklas Söderlund
2018-02-13 22:31       ` Laurent Pinchart
2018-02-13 23:12         ` Niklas Söderlund
2018-02-13 23:12           ` Niklas Söderlund
2018-02-13 23:28           ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 11/30] rcar-vin: move media bus configuration to struct rvin_info Niklas Söderlund
2018-02-13 16:37   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 12/30] rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 13/30] rcar-vin: add function to manipulate Gen3 chsel value Niklas Söderlund
2018-02-13 16:41   ` Laurent Pinchart
2018-02-13 16:58     ` Niklas Söderlund
2018-02-13 16:58       ` Niklas Söderlund
2018-02-13 17:02       ` Laurent Pinchart
2018-02-13 17:11         ` Niklas Söderlund
2018-02-13 17:11           ` Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 14/30] rcar-vin: add flag to switch to media controller mode Niklas Söderlund
2018-01-29 16:34 ` [PATCH v10 15/30] rcar-vin: break out format alignment and checking Niklas Söderlund
2018-02-13 16:56   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 16/30] rcar-vin: update bytesperline and sizeimage calculation Niklas Söderlund
2018-02-13 16:58   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 17/30] rcar-vin: update pixelformat check for M1 Niklas Söderlund
2018-02-13 17:03   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 18/30] rcar-vin: add check for colorspace Niklas Söderlund
2018-02-13 17:08   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 19/30] rcar-vin: set a default field to fallback on Niklas Söderlund
2018-02-13 17:51   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 20/30] rcar-vin: use different v4l2 operations in media controller mode Niklas Söderlund
2018-02-13 19:42   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 21/30] rcar-vin: prepare for media controller mode initialization Niklas Söderlund
2018-02-13 19:47   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 22/30] rcar-vin: add group allocator functions Niklas Söderlund
2018-02-13 20:09   ` Laurent Pinchart [this message]
2018-01-29 16:34 ` [PATCH v10 23/30] rcar-vin: change name of video device Niklas Söderlund
2018-02-13 20:10   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 24/30] rcar-vin: add chsel information to rvin_info Niklas Söderlund
2018-02-13 20:19   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 25/30] rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
2018-02-13 21:01   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 26/30] rcar-vin: add link notify for Gen3 Niklas Söderlund
2018-02-13 21:17   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 27/30] rcar-vin: extend {start,stop}_streaming to work with media controller Niklas Söderlund
2018-02-13 21:31   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 28/30] rcar-vin: enable support for r8a7795 Niklas Söderlund
2018-02-13 21:52   ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 29/30] rcar-vin: enable support for r8a7796 Niklas Söderlund
2018-02-13 21:54   ` Laurent Pinchart
2018-02-13 21:55     ` Laurent Pinchart
2018-01-29 16:34 ` [PATCH v10 30/30] rcar-vin: enable support for r8a77970 Niklas Söderlund
2018-02-13 21:56   ` Laurent Pinchart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1907646.jK4vy9bKSB@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=hverkuil@xs4all.nl \
    --cc=kieran.bingham@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=tomoharu.fukawa.eb@renesas.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.