All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Tommaso Merciai <tomm.merciai@gmail.com>,
	martin.hecht@avnet.eu, michael.roeder@avnet.eu,
	mhecht73@gmail.com, linuxfancy@googlegroups.com,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>,
	Hans de Goede <hdegoede@redhat.com>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,
	Marco Felsch <m.felsch@pengutronix.de>,
	Gerald Loacker <gerald.loacker@wolfvision.net>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	Daniel Scally <djrscally@gmail.com>,
	Shawn Tu <shawnx.tu@intel.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	linux-kernel@vger.kernel.org, linux-media@vger.kernel.org
Subject: Re: [PATCH v10 3/3] media: i2c: Add support for alvium camera
Date: Tue, 31 Oct 2023 10:53:47 +0200	[thread overview]
Message-ID: <20231031085347.GH12764@pendragon.ideasonboard.com> (raw)
In-Reply-To: <ZUCf_74Z0igCiJ_-@kekkonen.localdomain>

On Tue, Oct 31, 2023 at 06:34:39AM +0000, Sakari Ailus wrote:
> On Tue, Oct 31, 2023 at 01:38:09AM +0200, Laurent Pinchart wrote:
> > On Mon, Oct 30, 2023 at 10:43:47PM +0000, Sakari Ailus wrote:
> > > On Mon, Oct 30, 2023 at 01:26:58PM +0100, Tommaso Merciai wrote:
> > > 
> > > ...
> > > 
> > > > > > +static int alvium_get_host_supp_csi_lanes(struct alvium_dev *alvium)
> > > > > > +{
> > > > > > +	u64 val;
> > > > > > +	int ret = 0;
> > > > > > +
> > > > > > +	alvium_read(alvium, REG_BCRM_CSI2_LANE_COUNT_RW, &val, &ret);
> > > > > 
> > > > > Missing error checking before the use of the value. The same pattern
> > > > > remains prevalent throughout the driver.
> > > > > 
> > > > > I think it'd be easier if you didn't use a temporary variable for reading,
> > > > > but instead had a register width specific access function. You could even
> > > > > introduce a helper macro to read this information as I suggested in an
> > > > > earlier review.
> > > > 
> > > > oks.
> > > > We are moving to use the following macros:
> > > > 
> > > > #define alvium_read_check(alvium, reg, value) \
> > > > { \
> > > > 	int ret = alvium_read(alvium, reg, value, NULL); \
> > > > 	if (ret) \
> > > > 		return ret; \
> > > > }
> > > > 
> > > 
> > > You could do something like (entirely untested):
> > > 
> > > #define ALVIUM_DECLARE_READ(sign, bits) \
> > > 	static int
> > > 	alvium_read_ ## sign ## bits(struct alvium_dev *alvium, u32 reg, \
> > > 				     sign ## bits *val, int *err) \
> > > 	{ \
> > > 		u64 val64; \
> > > 		int ret; \
> > > 			\
> > > 		if (err && *err < 0) \
> > > 			return *err; \
> > > 			\
> > > 		alvium_read(alvium, reg, &val64, &ret); \
> > > 		if (ret < 0) { \
> > > 			if (err) \
> > > 				*err = ret; \
> > > 			return ret; \
> > > 		}	\
> > > 			\
> > > 		*val = val64; \
> > > 			\
> > > 		return 0; \
> > > 	}
> > > 
> > > ALVIUM_DECLARE_READ(u, 32);
> > > 
> > > And then, e.g. instead of (and failing to check ret):
> > > 
> > > 	u64 val;
> > > 
> > > 	alvium_read(alvium, REG_BCRM_CONTRAST_VALUE_RW, &val, &ret);
> > > 	alvium->dft_contrast = val;
> > > 
> > > you'd have a single call:
> > > 
> > > 	alvium_read_u32(alvium, REG_BCRM_CONTRAST_VALUE_RW,
> > > 		        &alvium->dft_contrast, &ret);
> > > 
> > > And so on.
> > > 
> > > You can drop sign if you don't need signed reads but some of the struct
> > > fields you're writing something appear to be signed.
> > > 
> > > It'd be good to check the register size matches with the size of *val, too.
> > > Maybe something like:
> > > 
> > > WARN_ON((CCI_REG ## bits(0) && CCI_REG_WIDTH_MASK) >> CCI_REG_WIDTH_SHIFT
> > > 	!= sizeof(sign ## bits));
> > 
> > I think this could actually be automated, and implemented in v4l2-cci.
> > Something like the following:
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
> > index bc2dbec019b0..27f1eaa7777d 100644
> > --- a/drivers/media/v4l2-core/v4l2-cci.c
> > +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > @@ -16,7 +16,7 @@
> > 
> >  #include <media/v4l2-cci.h>
> > 
> > -int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > +int __cci_read(struct regmap *map, u32 reg, void *val, int *err)
> >  {
> >  	unsigned int len;
> >  	u8 buf[8];
> > @@ -37,19 +37,19 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > 
> >  	switch (len) {
> >  	case 1:
> > -		*val = buf[0];
> > +		*(u8 *)val = buf[0];
> >  		break;
> >  	case 2:
> > -		*val = get_unaligned_be16(buf);
> > +		*(u16 *)val = get_unaligned_be16(buf);
> >  		break;
> >  	case 3:
> > -		*val = get_unaligned_be24(buf);
> > +		*(u32 *)val = get_unaligned_be24(buf);
> >  		break;
> >  	case 4:
> > -		*val = get_unaligned_be32(buf);
> > +		*(u32 *)val = get_unaligned_be32(buf);
> >  		break;
> >  	case 8:
> > -		*val = get_unaligned_be64(buf);
> > +		*(u64 *)val = get_unaligned_be64(buf);
> >  		break;
> >  	default:
> >  		dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
> > @@ -64,7 +64,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > 
> >  	return ret;
> >  }
> > -EXPORT_SYMBOL_GPL(cci_read);
> > +EXPORT_SYMBOL_GPL(__cci_read);
> > 
> >  int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
> >  {
> > @@ -119,7 +119,7 @@ int cci_update_bits(struct regmap *map, u32 reg, u64 mask, u64 val, int *err)
> >  	u64 readval;
> >  	int ret;
> > 
> > -	ret = cci_read(map, reg, &readval, err);
> > +	ret = __cci_read(map, reg, &readval, err);
> >  	if (ret)
> >  		return ret;
> > 
> > diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
> > index 0f6803e4b17e..31223ce8d741 100644
> > --- a/include/media/v4l2-cci.h
> > +++ b/include/media/v4l2-cci.h
> > @@ -7,6 +7,9 @@
> >  #ifndef _V4L2_CCI_H
> >  #define _V4L2_CCI_H
> > 
> > +#include <linux/bitfield.h>
> > +#include <linux/build_bug.h>
> > +#include <linux/log2.h>
> >  #include <linux/types.h>
> > 
> >  struct i2c_client;
> > @@ -39,6 +42,8 @@ struct cci_reg_sequence {
> >  #define CCI_REG32(x)			((4 << CCI_REG_WIDTH_SHIFT) | (x))
> >  #define CCI_REG64(x)			((8 << CCI_REG_WIDTH_SHIFT) | (x))
> > 
> > +int __cci_read(struct regmap *map, u32 reg, void *val, int *err);
> > +
> >  /**
> >   * cci_read() - Read a value from a single CCI register
> >   *
> > @@ -48,9 +53,17 @@ struct cci_reg_sequence {
> >   * @err: Optional pointer to store errors, if a previous error is set
> >   *       then the read will be skipped
> >   *
> > + * The type of the @val pointer must match the size of the register being read.
> > + * Mismatches will result in compile-time errors.
> > + *
> >   * Return: %0 on success or a negative error code on failure.
> >   */
> > -int cci_read(struct regmap *map, u32 reg, u64 *val, int *err);
> > +#define cci_read(map, reg, val, err) ({					\
> > +	u32 __reg = (reg);						\
> > +	u32 __size = FIELD_GET(CCI_REG_WIDTH_MASK, __reg);		\
> > +	BUILD_BUG_ON(sizeof(*(val)) != roundup_pow_of_two(__size));	\
> > +	__cci_read(map, __reg, (void *)(val), err);			\
> > +})
> > 
> >  /**
> >   * cci_write() - Write a value to a single CCI register
> > 
> > The change to cci_update_bits() is obviously wrong, I've hacked that to
> > compile-test the rest with the drivers using cci_read(), and I get nice
> > build-time errors due to usage of the wrong type :-)
> > 
> > Is this something that would be considered ? Bonus points to anyone who
> > would fix cci_update_bits() :-)
> 
> I like the idea of moving this to v4l2-cci.
> 
> I'd prefer _Generic() based solution as we'd have exact types there instead
> of just size. E.g. with the above code, reading a value to a long variable
> would work on some archs but fail on others.

Doesn't _Generic() treat compatible types identically ?

-- 
Regards,

Laurent Pinchart

  reply	other threads:[~2023-10-31  8:53 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-20 14:13 [PATCH v10 0/3] media: i2c: Add support for alvium camera Tommaso Merciai
2023-10-20 14:13 ` [PATCH v10 1/3] dt-bindings: vendor-prefixes: Add prefix alliedvision Tommaso Merciai
2023-10-20 14:13   ` Tommaso Merciai
2023-10-20 14:13 ` [PATCH v10 2/3] media: dt-bindings: alvium: add document YAML binding Tommaso Merciai
2023-10-20 14:13   ` Tommaso Merciai
2023-10-20 14:13 ` [PATCH v10 3/3] media: i2c: Add support for alvium camera Tommaso Merciai
2023-10-26 13:18   ` Sakari Ailus
2023-10-30 12:26     ` Tommaso Merciai
2023-10-30 12:37       ` Laurent Pinchart
2023-10-30 13:29         ` Tommaso Merciai
2023-10-30 13:37           ` Laurent Pinchart
2023-10-30 14:32             ` Tommaso Merciai
2023-10-30 14:44               ` Laurent Pinchart
2023-10-30 22:43       ` Sakari Ailus
2023-10-30 23:38         ` Laurent Pinchart
2023-10-31  6:34           ` Sakari Ailus
2023-10-31  8:53             ` Laurent Pinchart [this message]
2023-10-31  9:07               ` Sakari Ailus
2023-10-31 10:14                 ` Sakari Ailus
2023-10-31 10:18                   ` Laurent Pinchart
2023-10-31 10:34                     ` Sakari Ailus
2023-10-31 10:49                       ` Laurent Pinchart
2023-10-31  8:13         ` Tommaso Merciai
2023-10-31 10:23   ` Christophe JAILLET
2023-10-31 11:46     ` Tommaso Merciai
2023-11-01 14:13       ` Sakari Ailus
2023-11-01 14:22         ` Christophe JAILLET
2023-11-01 17:16           ` Tommaso Merciai
2023-11-01 20:10             ` Tommaso Merciai
2023-11-01 17:12         ` Tommaso Merciai

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=20231031085347.GH12764@pendragon.ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=broonie@kernel.org \
    --cc=djrscally@gmail.com \
    --cc=gerald.loacker@wolfvision.net \
    --cc=hdegoede@redhat.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=lgirdwood@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linuxfancy@googlegroups.com \
    --cc=m.felsch@pengutronix.de \
    --cc=martin.hecht@avnet.eu \
    --cc=mchehab@kernel.org \
    --cc=mhecht73@gmail.com \
    --cc=michael.roeder@avnet.eu \
    --cc=sakari.ailus@linux.intel.com \
    --cc=shawnx.tu@intel.com \
    --cc=tomi.valkeinen@ideasonboard.com \
    --cc=tomm.merciai@gmail.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.