From: "Gabbasov, Andrew" <Andrew_Gabbasov@mentor.com>
To: Wolfram Sang <wsa+renesas@sang-engineering.com>,
"linux-i2c@vger.kernel.org" <linux-i2c@vger.kernel.org>
Cc: "linux-renesas-soc@vger.kernel.org"
<linux-renesas-soc@vger.kernel.org>,
Eugeniu Rosca <erosca@de.adit-jv.com>,
"Surachari, Bhuvanesh" <Bhuvanesh_Surachari@mentor.com>
Subject: Re: [PATCH v4] i2c: rcar: add support for I2C_M_RECV_LEN
Date: Thu, 7 Apr 2022 11:13:55 +0000 [thread overview]
Message-ID: <1649330034935.59928@mentor.com> (raw)
In-Reply-To: <20220405100756.42920-1-wsa+renesas@sang-engineering.com>
Hello Wolfram,
Sorry for late response, I had some problems accessing my e-mail.
Thank you for your efforts on moving forward on this topic.
Indeed, this version of the patch combines all features/suggestions,
being discussed earlier, and looks quite compact and clear.
If you don't mind, I would propose one small "polishing" modification
(re-ordering of statements), that doesn't affect the functionality, see below.
________________________________________
> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Sent: Tuesday, April 5, 2022 13:07
> To: linux-i2c@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org; Eugeniu Rosca; Wolfram Sang; Surachari, Bhuvanesh; Gabbasov, Andrew
> Subject: [PATCH v4] i2c: rcar: add support for I2C_M_RECV_LEN
>
> [skipped]
>
> @@ -535,12 +537,29 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
> rcar_i2c_dma(priv);
> } else if (priv->pos < msg->len) {
> /* get received data */
> - msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX);
> + u8 data = rcar_i2c_read(priv, ICRXTX);
> +
> + msg->buf[priv->pos] = data;
> + if (recv_len_init) {
> + if (data == 0 || data > I2C_SMBUS_BLOCK_MAX) {
> + priv->flags |= ID_DONE | ID_EPROTO;
> + return;
> + }
> + msg->len += msg->buf[0];
> + /* Enough data for DMA? */
> + if (rcar_i2c_dma(priv))
> + return;
> + /* new length after RECV_LEN now properly initialized */
> + recv_len_init = false;
> + }
It looks like rcar_i2c_dma() starts DMA transfer at once, including to the transfer
the byte, currently residing in ICRXD register. (Because ICMSR.MDR bit is set.
That was the issue in my previous v2 patch: it copied the "current" byte to the
"next" buffer position too. To fix that, it would probably be necessary to clear
that bit before starting DMA, so that it starts with the next/pending bytes).
It means that this very first "length" byte will be copied to the buffer
by DMA transfer too (in addition to explicit assignment above).
So, I would propose to move the statement, placing the data byte to the buffer
("msg->buf[priv->pos] = data;"), to this place, after the "if (recv_len_init)" clause,
just before incrementing priv->pos.
Accordingly, adjustment of msg->len inside that "if" should be done using "data"
instead of "msg->buf[0]" ("msg->len += data;").
Besides avoiding of double assignment of that "length" byte to the buffer,
this move will avoid pollution of the buffer in case of an error (invalid length).
And will place filling in the data and position incrementation closer to each
other, that looks more "natural".
Again, this is just a "stylish" change, the patch looks good without it too ;-)
Thanks!
Best regards,
Andrew
> priv->pos++;
> }
>
> - /* If next received data is the _LAST_, go to new phase. */
> - if (priv->pos + 1 == msg->len) {
> + /*
> + * If next received data is the _LAST_ and we are not waiting for a new
> + * length because of RECV_LEN, then go to a new phase.
> + */
> + if (priv->pos + 1 == msg->len && !recv_len_init) {
> if (priv->flags & ID_LAST_MSG) {
> rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
> } else {
> @@ -847,6 +866,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
> ret = -ENXIO;
> } else if (priv->flags & ID_ARBLOST) {
> ret = -EAGAIN;
> + } else if (priv->flags & ID_EPROTO) {
> + ret = -EPROTO;
> } else {
> ret = num - priv->msgs_left; /* The number of transfer */
> }
> @@ -909,6 +930,8 @@ static int rcar_i2c_master_xfer_atomic(struct i2c_adapter *adap,
> ret = -ENXIO;
> } else if (priv->flags & ID_ARBLOST) {
> ret = -EAGAIN;
> + } else if (priv->flags & ID_EPROTO) {
> + ret = -EPROTO;
> } else {
> ret = num - priv->msgs_left; /* The number of transfer */
> }
> @@ -975,7 +998,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap)
> * I2C_M_IGNORE_NAK (automatically sends STOP after NAK)
> */
> u32 func = I2C_FUNC_I2C | I2C_FUNC_SLAVE |
> - (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
> + (I2C_FUNC_SMBUS_EMUL_ALL & ~I2C_FUNC_SMBUS_QUICK);
>
> if (priv->flags & ID_P_HOST_NOTIFY)
> func |= I2C_FUNC_SMBUS_HOST_NOTIFY;
> --
> 2.30.2
>
next prev parent reply other threads:[~2022-04-07 11:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-05 10:07 [PATCH v4] i2c: rcar: add support for I2C_M_RECV_LEN Wolfram Sang
2022-04-06 17:18 ` Eugeniu Rosca
2022-04-06 19:48 ` Wolfram Sang
2022-04-07 11:13 ` Gabbasov, Andrew [this message]
2022-04-07 12:18 ` Wolfram Sang
2022-04-07 12:42 ` Gabbasov, Andrew
2022-04-07 13:04 ` Wolfram Sang
2022-04-15 21:36 ` Wolfram Sang
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=1649330034935.59928@mentor.com \
--to=andrew_gabbasov@mentor.com \
--cc=Bhuvanesh_Surachari@mentor.com \
--cc=erosca@de.adit-jv.com \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=wsa+renesas@sang-engineering.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox