Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Antoni Pokusinski" <apokusinski01@gmail.com>
Cc: linux-rtc@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org,
	"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
	devicetree@vger.kernel.org
Subject: Re: [PATCH 3/6] rtc: abx80x: use regmap instead of I2C specific API
Date: Wed, 22 Jul 2026 20:16:45 +0000	[thread overview]
Message-ID: <20260722201646.115101F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260722195814.298552-4-apokusinski01@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Hardware unlock sequence is broken by read-modify-write inversion
- [Low] Incompatible pointer types passed to regmap_read()
--

--- Patch [3]: [PATCH 3/6] rtc: abx80x: use regmap instead of I2C specific API ---
commit 97cd1f33d168c96f848a8f59ba284bfe9c5f89fe
Author: Antoni Pokusinski <apokusinski01@gmail.com>
Date:   Wed Jul 22 19:58:11 2026 +0000

    rtc: abx80x: use regmap instead of I2C specific API
    
    Rework the driver so that it uses regmap_* functions for communication
    with the device instead of the i2c_smbus_* API. This way the support for
    ABX81X RTCs which use SPI can be added later.

> diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
> index 9b0e1d48d9ba3..e5ba821a67689 100644
> --- a/drivers/rtc/rtc-abx80x.c
> +++ b/drivers/rtc/rtc-abx80x.c
> @@ -125,52 +126,53 @@ static struct abx80x_cap abx80x_caps[] = {
[ ... ]
> -static int abx80x_is_rc_mode(struct i2c_client *client)
> +static int abx80x_is_rc_mode(struct device *dev)
>  {
> -	int flags = 0;
> +	struct abx80x_priv *priv = dev_get_drvdata(dev);
> +	int err, flags = 0;
>  
> -	flags =  i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
> -	if (flags < 0) {
> -		dev_err(&client->dev,
> -			"Failed to read autocalibration attribute\n");
> -		return flags;
> +	err = regmap_read(priv->regmap, ABX8XX_REG_OSS, &flags);

[Severity: Low]
Does this pass an incompatible pointer type to regmap_read()?

The API signature of regmap_read() expects an unsigned int * for its third
argument, but the address of a local int variable (&flags) is passed here.
While this may not cause memory corruption since int and unsigned int are
the same size, it violates the function signature and generates
-Wincompatible-pointer-types warnings, which can break builds compiling with
-Werror.

> +	if (err < 0) {
> +		dev_err(dev, "Failed to read autocalibration attribute\n");
> +		return err;
>  	}
[ ... ]
> @@ -259,13 +260,13 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  
>  static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
>  {
> -	struct i2c_client *client = dev_id;
> -	struct abx80x_priv *priv = i2c_get_clientdata(client);
> +	struct device *dev = dev_id;
> +	struct abx80x_priv *priv = dev_get_drvdata(dev);
>  	struct rtc_device *rtc = priv->rtc;
> -	int status;
> +	int err, status;
>  
> -	status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
> -	if (status < 0)
> +	err = regmap_read(priv->regmap, ABX8XX_REG_STATUS, &status);

[Severity: Low]
Does this pass an incompatible pointer type to regmap_read()?

Similar to abx80x_is_rc_mode() above, this passes an int pointer (&status)
instead of an unsigned int pointer.

> +	if (err < 0)
>  		return IRQ_NONE;
[ ... ]
> @@ -294,14 +294,13 @@ static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t)
>  	if (priv->irq <= 0)
>  		return -EINVAL;
>  
> -	err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ASC,
> -					    sizeof(buf), buf);
> +	err = regmap_bulk_read(priv->regmap, ABX8XX_REG_ASC, buf, sizeof(buf));
>  	if (err)
>  		return err;
>  
> -	irq_mask = i2c_smbus_read_byte_data(client, ABX8XX_REG_IRQ);
> -	if (irq_mask < 0)
> -		return irq_mask;
> +	err = regmap_read(priv->regmap, ABX8XX_REG_IRQ, &irq_mask);

[Severity: Low]
Does this pass an incompatible pointer type to regmap_read()?

This passes an int pointer (&irq_mask) instead of an unsigned int pointer.

> +	if (err < 0)
> +		return err;
[ ... ]
> @@ -379,22 +376,22 @@ static int abx80x_rtc_set_autocalibration(struct device *dev,
>  	}
>  
>  	/* Unlock write access to Oscillator Control Register */
> -	if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
> +	if (abx80x_write_config_key(dev, ABX8XX_CFG_KEY_OSC) < 0)
>  		return -EIO;
>  
> -	retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
> +	retval = regmap_write(priv->regmap, ABX8XX_REG_OSC, flags);

[Severity: High]
Does this hardware unlock sequence get broken by read-modify-write inversion?

According to the datasheet, any subsequent I2C access (read or write) resets
the configuration key to zero. If this sequence uses a read-modify-write
operation (such as regmap_write_bits()), a hardware read is performed after
the unlock key is written. This read resets the configuration key, causing the
hardware to ignore the subsequent write and breaking features like
autocalibration.

>  
>  	return retval;
>  }
>  
>  static int abx80x_rtc_get_autocalibration(struct device *dev)
>  {
> -	struct i2c_client *client = to_i2c_client(dev);
> -	int flags = 0, autocalibration;
> +	struct abx80x_priv *priv = dev_get_drvdata(dev);
> +	int flags = 0, autocalibration, err;
>  
> -	flags =  i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
> -	if (flags < 0)
> -		return flags;
> +	err = regmap_read(priv->regmap, ABX8XX_REG_OSC, &flags);

[Severity: Low]
Does this pass an incompatible pointer type to regmap_read()?

This passes an int pointer (&flags) instead of an unsigned int pointer.

> +	if (err < 0)
> +		return err;
[ ... ]
> @@ -467,10 +464,10 @@ static ssize_t oscillator_store(struct device *dev,
>  		flags |= (ABX8XX_OSC_OSEL);
>  
>  	/* Unlock write access on Oscillator Control register */
> -	if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
> +	if (abx80x_write_config_key(dev->parent, ABX8XX_CFG_KEY_OSC) < 0)
>  		return -EIO;
>  
> -	retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
> +	retval = regmap_write(priv->regmap, ABX8XX_REG_OSC, flags);

[Severity: High]
Does this hardware unlock sequence get broken by read-modify-write inversion?

As noted in abx80x_rtc_set_autocalibration() above, a hardware read performed
after the unlock key is written clears the key. This resets the key before the
protected write if a read-modify-write operation like regmap_write_bits() is
used.

>  	if (retval < 0) {
>  		dev_err(dev, "Failed to write Oscillator Control register\n");
[ ... ]
> @@ -513,45 +509,43 @@ static const struct attribute_group rtc_calib_attr_group = {
>  
>  static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
>  {
[ ... ]
>  static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
>  {
> -	struct i2c_client *client = to_i2c_client(dev);
> -	int status, tmp;
> +	struct abx80x_priv *priv = dev_get_drvdata(dev);
> +	int err, status, tmp;
>  
>  	switch (cmd) {
>  	case RTC_VL_READ:
> -		status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
> -		if (status < 0)
> -			return status;
> +		err = regmap_read(priv->regmap, ABX8XX_REG_STATUS, &status);

[Severity: Low]
Does this pass an incompatible pointer type to regmap_read()?

This passes an int pointer (&status) instead of an unsigned int pointer.

> +		if (err < 0)
> +			return err;
[ ... ]
> @@ -856,11 +898,11 @@ static int abx80x_probe(struct i2c_client *client)
>  		 * Write the configuration key register to enable access to
>  		 * the config2 register
>  		 */
> -		if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
> +		if (abx80x_write_config_key(&client->dev, ABX8XX_CFG_KEY_MISC) < 0)
>  			return -EIO;
>  
> -		err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL,
> -						data | ABX8XX_OUT_CTRL_EXDS);
> +		err = regmap_write(regmap, ABX8XX_REG_OUT_CTRL,
> +				   data | ABX8XX_OUT_CTRL_EXDS);

[Severity: High]
Does this hardware unlock sequence get broken by read-modify-write inversion?

For RV1805, the key is written, but if a read-modify-write operation like
regmap_write_bits() is used here, it performs a read before writing the EXTI
disable bit. This read clears the key, leaving the write ineffective and
defeating the extra power leakage workaround.

>  		if (err < 0) {
>  			dev_err(&client->dev,
>  				"Unable to write output control register\n");

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722195814.298552-1-apokusinski01@gmail.com?part=3

  reply	other threads:[~2026-07-22 20:16 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22 19:58 [PATCH 0/6] rtc: abx80x: add support for ABX81X Antoni Pokusinski
2026-07-22 19:58 ` [PATCH 1/6] dt-bindings: rtc: abx80x: document ABX81X RTCs Antoni Pokusinski
2026-07-22 20:09   ` sashiko-bot
2026-07-22 19:58 ` [PATCH 2/6] rtc: abx80x: add irq to struct abx80x_priv Antoni Pokusinski
2026-07-22 20:13   ` sashiko-bot
2026-07-22 19:58 ` [PATCH 3/6] rtc: abx80x: use regmap instead of I2C specific API Antoni Pokusinski
2026-07-22 20:16   ` sashiko-bot [this message]
2026-07-22 19:58 ` [PATCH 4/6] rtc: abx80x: replace read-modify-write pattern with regmap helpers Antoni Pokusinski
2026-07-22 20:11   ` sashiko-bot
2026-07-22 19:58 ` [PATCH 5/6] rtc: abx80x: create abx80x_i2c_probe() Antoni Pokusinski
2026-07-22 20:10   ` sashiko-bot
2026-07-22 19:58 ` [PATCH 6/6] rtc: abx80x: add support for ABX81X Antoni Pokusinski
2026-07-22 20:09   ` sashiko-bot

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=20260722201646.115101F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alexandre.belloni@bootlin.com \
    --cc=apokusinski01@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox