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 v9 21/28] rcar-vin: add group allocator functions
Date: Fri, 08 Dec 2017 22:12:56 +0200 [thread overview]
Message-ID: <2338267.IAVXeh1rRr@avalon> (raw)
In-Reply-To: <20171208010842.20047-22-niklas.soderlund+renesas@ragnatech.se>
Hi Niklas,
Thank you for the patch.
On Friday, 8 December 2017 03:08:35 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 to each VIN instance to know 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 creates a media device.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> drivers/media/platform/rcar-vin/rcar-core.c | 179 ++++++++++++++++++++++++-
> drivers/media/platform/rcar-vin/rcar-vin.h | 38 ++++++
> 2 files changed, 215 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c
> b/drivers/media/platform/rcar-vin/rcar-core.c index
> 45de4079fd835759..a6713fd61dd87a88 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -20,12 +20,170 @@
> #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
> + */
> +
> +static int rvin_group_read_id(struct rvin_dev *vin, struct device_node *np)
> +{
> + u32 val;
> + int ret;
> +
> + ret = of_property_read_u32(np, "renesas,id", &val);
> + if (ret) {
> + vin_err(vin, "%pOF: No renesas,id property found\n", np);
> + return -EINVAL;
> + }
> +
> + if (val >= RCAR_VIN_NUM) {
> + vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", np, val);
> + return -EINVAL;
> + }
I'd move all this to the main DT parsing function.
> + return val;
> +}
> +
> +static DEFINE_MUTEX(rvin_group_lock);
> +static struct rvin_group *rvin_group_data;
Nitpicking, static variables are often defined at the beginning of the C file,
before any function. I'll let you decide whether you want to move them.
> +static void rvin_group_release(struct kref *kref)
> +{
> + struct rvin_group *group =
> + container_of(kref, struct rvin_group, refcount);
> +
> + mutex_lock(&rvin_group_lock);
> +
> + media_device_unregister(&group->mdev);
> + media_device_cleanup(&group->mdev);
> +
> + rvin_group_data = NULL;
> +
> + mutex_unlock(&rvin_group_lock);
> +
> + kfree(group);
> +}
> +
> +static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin)
> +{
> + struct rvin_group *group;
> +
> + if (rvin_group_data) {
> + group = rvin_group_data;
> + kref_get(&group->refcount);
> + vin_dbg(vin, "%s: get group=%p\n", __func__, group);
> + return group;
> + }
> +
> + group = kzalloc(sizeof(*group), GFP_KERNEL);
> + if (!group)
> + return NULL;
> +
> + kref_init(&group->refcount);
> + rvin_group_data = group;
Ouch. While I agree with the global mutex, a single global group variable
reminds me of the days when per-device data was happily stored in global
variables because, you know, we will never have more than one instance of that
device, right ? (Or, sometimes, because the driver author didn't know what an
instance was.)
Ideally we'd want a linked list of groups, and this function would either
retrieve the group that the VIN instance is part of, or allocate a new one.
> + vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
Do you still need those two debug statements (and all of the other ones below)
?
> + return group;
> +}
> +
> +static int rvin_group_add_vin(struct rvin_dev *vin)
> +{
> + int ret;
> +
> + ret = rvin_group_read_id(vin, vin->dev->of_node);
> + if (ret < 0)
> + return ret;
> +
> + mutex_lock(&vin->group->lock);
> +
> + if (vin->group->vin[ret]) {
> + mutex_unlock(&vin->group->lock);
> + vin_err(vin, "VIN number %d already occupied\n", ret);
> + return -EINVAL;
Can this happen ?
> + }
> +
> + vin->group->vin[ret] = vin;
> +
> + mutex_unlock(&vin->group->lock);
> +
> + vin_dbg(vin, "I'm VIN number %d", ret);
> +
> + return 0;
> +}
> +
> +static int rvin_group_allocate(struct rvin_dev *vin)
> +{
> + struct rvin_group *group;
> + struct media_device *mdev;
> + int ret;
> +
> + mutex_lock(&rvin_group_lock);
> +
> + group = __rvin_group_allocate(vin);
> + if (!group) {
> + mutex_unlock(&rvin_group_lock);
I'd use a goto unlock instead of spreading mutex_unlock() calls through the
function. It's easier to locate a misplaced return in a function that should
only use gotos than a missing mutex_unlock().
> + return -ENOMEM;
> + }
> +
> + /* Init group data if it is not already initialized */
> + mdev = &group->mdev;
> + if (!mdev->dev) {
> + mutex_init(&group->lock);
> + mdev->dev = vin->dev;
> +
> + strlcpy(mdev->driver_name, "Renesas VIN",
> + sizeof(mdev->driver_name));
How about using the module name ?
> + strlcpy(mdev->model, vin->dev->of_node->name,
> + sizeof(mdev->model));
I wonder whether you shouldn't somehow use the compatible string to create the
model name, in order to accurately report the device model.
> + snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
> + dev_name(mdev->dev));
> + media_device_init(mdev);
> +
> + ret = media_device_register(mdev);
> + if (ret) {
> + vin_err(vin, "Failed to register media device\n");
> + kref_put(&group->refcount, rvin_group_release);
This will deadlock if you're releasing the last reference. There's an
identical issue below.
> + mutex_unlock(&rvin_group_lock);
> + return ret;
> + }
> + }
> +
> + vin->group = group;
> + vin->v4l2_dev.mdev = mdev;
> +
> + ret = rvin_group_add_vin(vin);
I'd inline the function here.
> + if (ret) {
> + kref_put(&group->refcount, rvin_group_release);
> + mutex_unlock(&rvin_group_lock);
> + return ret;
> + }
> +
> + mutex_unlock(&rvin_group_lock);
> +
> + return 0;
> +}
> +
> +static void rvin_group_delete(struct rvin_dev *vin)
This function doesn't completely delete the group, it only drops one
reference. How about rvin_group_put() ? rvin_group_allocate() could then be
called rvin_group_get().
> +{
> + unsigned int i;
> +
> + mutex_lock(&vin->group->lock);
> + for (i = 0; i < RCAR_VIN_NUM; i++)
> + if (vin->group->vin[i] == vin)
> + vin->group->vin[i] = NULL;
> + mutex_unlock(&vin->group->lock);
> +
> + vin_dbg(vin, "%s: group=%p\n", __func__, &vin->group);
> + kref_put(&vin->group->refcount, rvin_group_release);
> +}
> +
> /* ------------------------------------------------------------------------
> * Async notifier
> */
> @@ -236,12 +394,27 @@ static int rvin_digital_graph_init(struct rvin_dev
> *vin)
>
> static int rvin_group_init(struct rvin_dev *vin)
> {
> + int ret;
> +
> + ret = rvin_group_allocate(vin);
> + if (ret)
> + return 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)
> + goto error_group;
> +
> + return 0;
> +
> +error_group:
> + rvin_group_delete(vin);
> +
> + return ret;
> }
>
> /* ------------------------------------------------------------------------
> @@ -361,7 +534,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_delete(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
> 07d270a976893cdb..5f736a3500b6e10f 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>
> @@ -30,6 +32,9 @@
> /* 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
> +
> enum chip_id {
> RCAR_H1,
> RCAR_M1,
> @@ -37,6 +42,15 @@ enum chip_id {
> RCAR_GEN3,
> };
>
> +enum rvin_csi_id {
> + RVIN_CSI20,
> + RVIN_CSI21,
> + RVIN_CSI40,
> + RVIN_CSI41,
> + RVIN_CSI_MAX,
> + RVIN_NC, /* Not Connected */
> +};
> +
> /**
> * STOPPED - No operation in progress
> * RUNNING - Operation in progress have buffers
> @@ -75,6 +89,8 @@ struct rvin_graph_entity {
> unsigned int sink_pad;
> };
>
> +struct rvin_group;
Forward declarations are usually grouped at the beginning of the header.
> /**
> * struct rvin_info - Information about the particular VIN implementation
> * @chip: type of VIN chip
> @@ -103,6 +119,7 @@ struct rvin_info {
> * @notifier: V4L2 asynchronous subdevs notifier
> * @digital: entity in the DT for local digital subdevice
> *
> + * @group: Gen3 CSI group
> * @pad: pad for media controller
> *
> * @lock: protects @queue
> @@ -134,6 +151,7 @@ struct rvin_dev {
> struct v4l2_async_notifier notifier;
> struct rvin_graph_entity *digital;
>
> + struct rvin_group *group;
> struct media_pad pad;
>
> struct mutex lock;
> @@ -162,6 +180,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 vin and csi members
> + * @vin: VIN instances which are part of the group
> + * @csi: CSI-2 entities that are part of the group
> + */
> +struct rvin_group {
> + struct kref refcount;
> +
> + struct media_device mdev;
> +
> + struct mutex lock;
> + struct rvin_dev *vin[RCAR_VIN_NUM];
> + struct rvin_graph_entity csi[RVIN_CSI_MAX];
Given that the number and types of CSI receivers varies quite a bit between
SoCs I wonder whether this couldn't be a linked list. If csi was an array of
pointers it would be less of an issue, but an array of rvin_graph_entity can
grow large.
> +};
> +
> int rvin_dma_register(struct rvin_dev *vin, int irq);
> void rvin_dma_unregister(struct rvin_dev *vin);
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2017-12-08 20:12 UTC|newest]
Thread overview: 97+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-08 1:08 [PATCH v9 00/28] rcar-vin: Add Gen3 with media controller Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 01/28] rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
2017-12-08 7:46 ` Laurent Pinchart
2017-12-08 12:55 ` Niklas Söderlund
2017-12-08 12:55 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 02/28] rcar-vin: rename poorly named initialize and cleanup functions Niklas Söderlund
2017-12-08 7:49 ` Laurent Pinchart
2017-12-08 12:58 ` Niklas Söderlund
2017-12-08 12:58 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 03/28] rcar-vin: unregister video device on driver removal Niklas Söderlund
2017-12-08 7:54 ` Laurent Pinchart
2017-12-08 8:46 ` Hans Verkuil
2017-12-08 8:49 ` Laurent Pinchart
2017-12-08 13:09 ` Niklas Söderlund
2017-12-08 13:09 ` Niklas Söderlund
2017-12-08 19:07 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 04/28] rcar-vin: move subdevice handling to async callbacks Niklas Söderlund
2017-12-08 8:03 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 05/28] rcar-vin: move chip information to own struct Niklas Söderlund
2017-12-08 8:08 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 06/28] rcar-vin: move max width and height information to chip information Niklas Söderlund
2017-12-08 8:10 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 07/28] rcar-vin: change name of video device Niklas Söderlund
2017-12-08 8:17 ` Laurent Pinchart
2017-12-14 14:25 ` Sakari Ailus
2017-12-14 14:25 ` Sakari Ailus
2017-12-14 15:50 ` Laurent Pinchart
2017-12-20 15:20 ` Niklas Söderlund
2017-12-20 15:20 ` Niklas Söderlund
2018-01-08 16:35 ` Laurent Pinchart
2018-01-08 16:42 ` Niklas Söderlund
2018-01-08 16:42 ` Niklas Söderlund
2018-01-08 17:48 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 08/28] rcar-vin: move functions regarding scaling Niklas Söderlund
2017-12-08 8:28 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 09/28] rcar-vin: all Gen2 boards can scale simplify logic Niklas Söderlund
2017-12-08 8:33 ` Laurent Pinchart
2017-12-20 16:17 ` Niklas Söderlund
2017-12-20 16:17 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 10/28] rcar-vin: do not reset crop and compose when setting format Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 11/28] rcar-vin: do not allow changing scaling and composing while streaming Niklas Söderlund
2017-12-08 9:04 ` Laurent Pinchart
2017-12-08 14:14 ` Niklas Söderlund
2017-12-08 14:14 ` Niklas Söderlund
2017-12-08 19:20 ` Laurent Pinchart
2017-12-20 16:26 ` Niklas Söderlund
2017-12-20 16:26 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 12/28] rcar-vin: read subdevice format for crop only when needed Niklas Söderlund
2017-12-08 9:11 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 13/28] rcar-vin: fix handling of single field frames (top, bottom and alternate fields) Niklas Söderlund
2017-12-08 9:35 ` Laurent Pinchart
2017-12-08 14:06 ` Niklas Söderlund
2017-12-08 14:06 ` Niklas Söderlund
2017-12-08 19:30 ` Laurent Pinchart
2017-12-20 17:17 ` Niklas Söderlund
2017-12-20 17:17 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 14/28] rcar-vin: move media bus configuration to struct rvin_info Niklas Söderlund
2017-12-08 9:40 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 15/28] rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
2017-12-08 9:47 ` Laurent Pinchart
2017-12-20 21:09 ` Niklas Söderlund
2017-12-20 21:09 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 16/28] rcar-vin: add function to manipulate Gen3 chsel value Niklas Söderlund
2017-12-08 9:52 ` Laurent Pinchart
2017-12-20 21:20 ` Niklas Söderlund
2017-12-20 21:20 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 17/28] rcar-vin: add flag to switch to media controller mode Niklas Söderlund
2017-12-08 9:52 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 18/28] rcar-vin: break out format alignment and checking Niklas Söderlund
2017-12-08 10:01 ` Laurent Pinchart
2017-12-21 0:25 ` Niklas Söderlund
2017-12-21 0:25 ` Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 19/28] rcar-vin: use different v4l2 operations in media controller mode Niklas Söderlund
2017-12-08 10:14 ` Laurent Pinchart
2017-12-08 10:24 ` Hans Verkuil
2017-12-08 19:31 ` Laurent Pinchart
2018-01-19 0:46 ` Niklas Söderlund
2018-01-19 0:46 ` Niklas Söderlund
2018-03-02 11:33 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 20/28] rcar-vin: prepare for media controller mode initialization Niklas Söderlund
2017-12-08 10:20 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 21/28] rcar-vin: add group allocator functions Niklas Söderlund
2017-12-08 20:12 ` Laurent Pinchart [this message]
2018-01-08 17:24 ` Niklas Söderlund
2018-01-08 17:24 ` Niklas Söderlund
2018-01-08 17:57 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 22/28] rcar-vin: add chsel information to rvin_info Niklas Söderlund
2017-12-08 20:37 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 23/28] rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 24/28] rcar-vin: add link notify for Gen3 Niklas Söderlund
2017-12-08 1:08 ` [PATCH v9 25/28] rcar-vin: extend {start,stop}_streaming to work with media controller Niklas Söderlund
2017-12-08 20:45 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 26/28] rcar-vin: enable support for r8a7795 Niklas Söderlund
2017-12-08 10:21 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 27/28] rcar-vin: enable support for r8a7796 Niklas Söderlund
2017-12-08 10:25 ` Laurent Pinchart
2017-12-08 1:08 ` [PATCH v9 28/28] rcar-vin: enable support for r8a77970 Niklas Söderlund
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=2338267.IAVXeh1rRr@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.