* [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
@ 2015-02-15 14:43 Yoshihiro Kaneko
2015-02-23 13:07 ` Wolfram Sang
0 siblings, 1 reply; 8+ messages in thread
From: Yoshihiro Kaneko @ 2015-02-15 14:43 UTC (permalink / raw)
To: linux-i2c; +Cc: Wolfram Sang, Simon Horman, Magnus Damm, linux-sh
From: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
In case of repeated START condition, the restart has to be kicked
before clear status (MSR register). If it is kicked after clear status,
R-Car I2C may transfer data (TXD register) or receive data (RXD register)
instead of transferring slave address (MAR register).
Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
---
This patch is based on i2c/for-next branch of Wolfram Sang's linux tree.
drivers/i2c/busses/i2c-rcar.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 71a6e07..96c349f 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -2,6 +2,7 @@
* Driver for the Renesas RCar I2C unit
*
* Copyright (C) 2014 Wolfram Sang <wsa@sang-engineering.com>
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
*
* Copyright (C) 2012-14 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
@@ -99,6 +100,7 @@
#define ID_DONE (1 << 2)
#define ID_ARBLOST (1 << 3)
#define ID_NACK (1 << 4)
+#define ID_FIRST_MSG (1 << 5)
enum rcar_i2c_type {
I2C_RCAR_GEN1,
@@ -125,6 +127,7 @@ struct rcar_i2c_priv {
#define rcar_i2c_is_recv(p) ((p)->msg->flags & I2C_M_RD)
#define rcar_i2c_flags_set(p, f) ((p)->flags |= (f))
+#define rcar_i2c_flags_clr(p, f) ((p)->flags &= ~(f))
#define rcar_i2c_flags_has(p, f) ((p)->flags & (f))
#define LOOP_TIMEOUT 1024
@@ -257,8 +260,14 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
int read = !!rcar_i2c_is_recv(priv);
rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read);
- rcar_i2c_write(priv, ICMSR, 0);
- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+ if (rcar_i2c_flags_has(priv, ID_FIRST_MSG)) { /* start */
+ rcar_i2c_write(priv, ICMSR, 0);
+ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+ rcar_i2c_flags_clr(priv, ID_FIRST_MSG);
+ } else { /* restart */
+ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+ rcar_i2c_write(priv, ICMSR, 0);
+ }
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
}
@@ -524,6 +533,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
priv->msg = &msgs[i];
priv->pos = 0;
priv->flags = 0;
+ if (i = 0)
+ rcar_i2c_flags_set(priv, ID_FIRST_MSG);
if (i = num - 1)
rcar_i2c_flags_set(priv, ID_LAST_MSG);
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-02-15 14:43 [PATCH/RFC] i2c: rcar: Fix order of restart and clear status Yoshihiro Kaneko
@ 2015-02-23 13:07 ` Wolfram Sang
2015-03-04 4:08 ` Simon Horman
0 siblings, 1 reply; 8+ messages in thread
From: Wolfram Sang @ 2015-02-23 13:07 UTC (permalink / raw)
To: Yoshihiro Kaneko; +Cc: linux-i2c, Simon Horman, Magnus Damm, linux-sh
Hi,
On 2015-02-15 15:43, Yoshihiro Kaneko wrote:
> From: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
>
> In case of repeated START condition, the restart has to be kicked
> before clear status (MSR register). If it is kicked after clear
> status,
> R-Car I2C may transfer data (TXD register) or receive data (RXD
> register)
> instead of transferring slave address (MAR register).
>
> Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
Thanks for the patch!
I wondered if we couldn't always kick the start/restart before clearing
the status register?
I am not sure if this simulates the flaw accurately, but I inserted a
udelay(500)
in the original code after clearing the status register. Then, I
couldn't access
the audio codec on my Lager board anymore. By always first "kicking"
and then
clearing, access was possible again. But as said, I am not sure if my
scenario
matches yours. Have you considered to treat start and repeated start
the same
and always kick the condition before clearing the status?
Kind regards,
Wolfram
> ---
>
> This patch is based on i2c/for-next branch of Wolfram Sang's linux
> tree.
>
> drivers/i2c/busses/i2c-rcar.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-rcar.c
> b/drivers/i2c/busses/i2c-rcar.c
> index 71a6e07..96c349f 100644
> --- a/drivers/i2c/busses/i2c-rcar.c
> +++ b/drivers/i2c/busses/i2c-rcar.c
> @@ -2,6 +2,7 @@
> * Driver for the Renesas RCar I2C unit
> *
> * Copyright (C) 2014 Wolfram Sang <wsa@sang-engineering.com>
> + * Copyright (C) 2013-2014 Renesas Electronics Corporation
> *
> * Copyright (C) 2012-14 Renesas Solutions Corp.
> * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> @@ -99,6 +100,7 @@
> #define ID_DONE (1 << 2)
> #define ID_ARBLOST (1 << 3)
> #define ID_NACK (1 << 4)
> +#define ID_FIRST_MSG (1 << 5)
>
> enum rcar_i2c_type {
> I2C_RCAR_GEN1,
> @@ -125,6 +127,7 @@ struct rcar_i2c_priv {
> #define rcar_i2c_is_recv(p) ((p)->msg->flags & I2C_M_RD)
>
> #define rcar_i2c_flags_set(p, f) ((p)->flags |= (f))
> +#define rcar_i2c_flags_clr(p, f) ((p)->flags &= ~(f))
> #define rcar_i2c_flags_has(p, f) ((p)->flags & (f))
>
> #define LOOP_TIMEOUT 1024
> @@ -257,8 +260,14 @@ static void rcar_i2c_prepare_msg(struct
> rcar_i2c_priv *priv)
> int read = !!rcar_i2c_is_recv(priv);
>
> rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read);
> - rcar_i2c_write(priv, ICMSR, 0);
> - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
> + if (rcar_i2c_flags_has(priv, ID_FIRST_MSG)) { /* start */
> + rcar_i2c_write(priv, ICMSR, 0);
> + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
> + rcar_i2c_flags_clr(priv, ID_FIRST_MSG);
> + } else { /* restart */
> + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
> + rcar_i2c_write(priv, ICMSR, 0);
> + }
> rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
> }
>
> @@ -524,6 +533,8 @@ static int rcar_i2c_master_xfer(struct
> i2c_adapter *adap,
> priv->msg = &msgs[i];
> priv->pos = 0;
> priv->flags = 0;
> + if (i = 0)
> + rcar_i2c_flags_set(priv, ID_FIRST_MSG);
> if (i = num - 1)
> rcar_i2c_flags_set(priv, ID_LAST_MSG);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-02-23 13:07 ` Wolfram Sang
@ 2015-03-04 4:08 ` Simon Horman
2015-03-06 22:05 ` Wolfram Sang
0 siblings, 1 reply; 8+ messages in thread
From: Simon Horman @ 2015-03-04 4:08 UTC (permalink / raw)
To: Wolfram Sang; +Cc: Yoshihiro Kaneko, linux-i2c, Magnus Damm, linux-sh
Hi Wolfram,
On Mon, Feb 23, 2015 at 02:07:18PM +0100, Wolfram Sang wrote:
> Hi,
>
> On 2015-02-15 15:43, Yoshihiro Kaneko wrote:
> >From: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
> >
> >In case of repeated START condition, the restart has to be kicked
> >before clear status (MSR register). If it is kicked after clear status,
> >R-Car I2C may transfer data (TXD register) or receive data (RXD register)
> >instead of transferring slave address (MAR register).
> >
> >Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
> >Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
>
> Thanks for the patch!
>
> I wondered if we couldn't always kick the start/restart before clearing
> the status register?
I asked Kataoka-san about this and his response was as follows:
If system(CPU) is busy, the driver can't clear the status register soon
after kicking start.
If sequence of first start is as follows, there is a problem.
Because H/W starts by 1.
But sequence of re-start is as follows, there is no problem.
Because H/W starts by 2.
1. Issue START condition by ESG bit of ICMCR register.
<--- If there is too much time, H/W finish transmitting
and set status in status register.
2. Clear interrupt status (ICMSR).
3. Open interrupt mask.
4. Wait interrupt.
<--- If status is cleared, interrupt does not occur.
> I am not sure if this simulates the flaw accurately, but I inserted a
> udelay(500) in the original code after clearing the status register.
> Then, I couldn't access the audio codec on my Lager board anymore. By
> always first "kicking" and then clearing, access was possible again. But
> as said, I am not sure if my scenario matches yours. Have you considered
> to treat start and repeated start the same and always kick the condition
> before clearing the status?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-03-04 4:08 ` Simon Horman
@ 2015-03-06 22:05 ` Wolfram Sang
2015-03-07 10:33 ` Wolfram Sang
0 siblings, 1 reply; 8+ messages in thread
From: Wolfram Sang @ 2015-03-06 22:05 UTC (permalink / raw)
To: Simon Horman; +Cc: Yoshihiro Kaneko, linux-i2c, Magnus Damm, linux-sh
[-- Attachment #1: Type: text/plain, Size: 823 bytes --]
> I asked Kataoka-san about this and his response was as follows:
Thanks, Simon!
> If system(CPU) is busy, the driver can't clear the status register soon
> after kicking start.
>
> If sequence of first start is as follows, there is a problem.
> Because H/W starts by 1.
> But sequence of re-start is as follows, there is no problem.
> Because H/W starts by 2.
>
> 1. Issue START condition by ESG bit of ICMCR register.
> <--- If there is too much time, H/W finish transmitting
> and set status in status register.
> 2. Clear interrupt status (ICMSR).
> 3. Open interrupt mask.
> 4. Wait interrupt.
> <--- If status is cleared, interrupt does not occur.
I understand. I'll add this explanation to the patch and apply it soon.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-03-06 22:05 ` Wolfram Sang
@ 2015-03-07 10:33 ` Wolfram Sang
2015-03-27 13:10 ` Wolfram Sang
0 siblings, 1 reply; 8+ messages in thread
From: Wolfram Sang @ 2015-03-07 10:33 UTC (permalink / raw)
To: Simon Horman; +Cc: Yoshihiro Kaneko, linux-i2c, Magnus Damm, linux-sh
[-- Attachment #1: Type: text/plain, Size: 1143 bytes --]
On Fri, Mar 06, 2015 at 11:05:31PM +0100, Wolfram Sang wrote:
>
> > I asked Kataoka-san about this and his response was as follows:
>
> Thanks, Simon!
>
> > If system(CPU) is busy, the driver can't clear the status register soon
> > after kicking start.
> >
> > If sequence of first start is as follows, there is a problem.
> > Because H/W starts by 1.
> > But sequence of re-start is as follows, there is no problem.
> > Because H/W starts by 2.
> >
> > 1. Issue START condition by ESG bit of ICMCR register.
> > <--- If there is too much time, H/W finish transmitting
> > and set status in status register.
> > 2. Clear interrupt status (ICMSR).
> > 3. Open interrupt mask.
> > 4. Wait interrupt.
> > <--- If status is cleared, interrupt does not occur.
>
> I understand. I'll add this explanation to the patch and apply it soon.
Sorry, another question came up while applying:
How can this interruption happen? The function is called in a
spin_lock_irqsave protected area. Is this an RT_PREEMPT related issue?
Am I missing something?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-03-07 10:33 ` Wolfram Sang
@ 2015-03-27 13:10 ` Wolfram Sang
2015-03-30 0:15 ` Simon Horman
0 siblings, 1 reply; 8+ messages in thread
From: Wolfram Sang @ 2015-03-27 13:10 UTC (permalink / raw)
To: Simon Horman
Cc: Yoshihiro Kaneko, linux-i2c-u79uwXL29TY76Z2rM5mHXA, Magnus Damm,
linux-sh-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 1327 bytes --]
On Sat, Mar 07, 2015 at 11:33:49AM +0100, Wolfram Sang wrote:
> On Fri, Mar 06, 2015 at 11:05:31PM +0100, Wolfram Sang wrote:
> >
> > > I asked Kataoka-san about this and his response was as follows:
> >
> > Thanks, Simon!
> >
> > > If system(CPU) is busy, the driver can't clear the status register soon
> > > after kicking start.
> > >
> > > If sequence of first start is as follows, there is a problem.
> > > Because H/W starts by 1.
> > > But sequence of re-start is as follows, there is no problem.
> > > Because H/W starts by 2.
> > >
> > > 1. Issue START condition by ESG bit of ICMCR register.
> > > <--- If there is too much time, H/W finish transmitting
> > > and set status in status register.
> > > 2. Clear interrupt status (ICMSR).
> > > 3. Open interrupt mask.
> > > 4. Wait interrupt.
> > > <--- If status is cleared, interrupt does not occur.
> >
> > I understand. I'll add this explanation to the patch and apply it soon.
>
> Sorry, another question came up while applying:
>
> How can this interruption happen? The function is called in a
> spin_lock_irqsave protected area. Is this an RT_PREEMPT related issue?
> Am I missing something?
Hi,
any news on this one?
Kind regards,
Wolfram
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-03-27 13:10 ` Wolfram Sang
@ 2015-03-30 0:15 ` Simon Horman
2015-05-18 6:04 ` Simon Horman
0 siblings, 1 reply; 8+ messages in thread
From: Simon Horman @ 2015-03-30 0:15 UTC (permalink / raw)
To: Wolfram Sang
Cc: Yoshihiro Kaneko, linux-i2c-u79uwXL29TY76Z2rM5mHXA, Magnus Damm,
linux-sh-u79uwXL29TY76Z2rM5mHXA
On Fri, Mar 27, 2015 at 02:10:45PM +0100, Wolfram Sang wrote:
> On Sat, Mar 07, 2015 at 11:33:49AM +0100, Wolfram Sang wrote:
> > On Fri, Mar 06, 2015 at 11:05:31PM +0100, Wolfram Sang wrote:
> > >
> > > > I asked Kataoka-san about this and his response was as follows:
> > >
> > > Thanks, Simon!
> > >
> > > > If system(CPU) is busy, the driver can't clear the status register soon
> > > > after kicking start.
> > > >
> > > > If sequence of first start is as follows, there is a problem.
> > > > Because H/W starts by 1.
> > > > But sequence of re-start is as follows, there is no problem.
> > > > Because H/W starts by 2.
> > > >
> > > > 1. Issue START condition by ESG bit of ICMCR register.
> > > > <--- If there is too much time, H/W finish transmitting
> > > > and set status in status register.
> > > > 2. Clear interrupt status (ICMSR).
> > > > 3. Open interrupt mask.
> > > > 4. Wait interrupt.
> > > > <--- If status is cleared, interrupt does not occur.
> > >
> > > I understand. I'll add this explanation to the patch and apply it soon.
> >
> > Sorry, another question came up while applying:
> >
> > How can this interruption happen? The function is called in a
> > spin_lock_irqsave protected area. Is this an RT_PREEMPT related issue?
> > Am I missing something?
>
> Hi,
>
> any news on this one?
Sorry, I seem to have dropped the ball here. I've (finally) forwarded
your question on to the BSP team.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] i2c: rcar: Fix order of restart and clear status
2015-03-30 0:15 ` Simon Horman
@ 2015-05-18 6:04 ` Simon Horman
0 siblings, 0 replies; 8+ messages in thread
From: Simon Horman @ 2015-05-18 6:04 UTC (permalink / raw)
To: Wolfram Sang; +Cc: Yoshihiro Kaneko, linux-i2c, Magnus Damm, linux-sh
Hi Wolfram,
On Mon, Mar 30, 2015 at 09:15:30AM +0900, Simon Horman wrote:
> On Fri, Mar 27, 2015 at 02:10:45PM +0100, Wolfram Sang wrote:
> > On Sat, Mar 07, 2015 at 11:33:49AM +0100, Wolfram Sang wrote:
> > > On Fri, Mar 06, 2015 at 11:05:31PM +0100, Wolfram Sang wrote:
> > > >
> > > > > I asked Kataoka-san about this and his response was as follows:
> > > >
> > > > Thanks, Simon!
> > > >
> > > > > If system(CPU) is busy, the driver can't clear the status register soon
> > > > > after kicking start.
> > > > >
> > > > > If sequence of first start is as follows, there is a problem.
> > > > > Because H/W starts by 1.
> > > > > But sequence of re-start is as follows, there is no problem.
> > > > > Because H/W starts by 2.
> > > > >
> > > > > 1. Issue START condition by ESG bit of ICMCR register.
> > > > > <--- If there is too much time, H/W finish transmitting
> > > > > and set status in status register.
> > > > > 2. Clear interrupt status (ICMSR).
> > > > > 3. Open interrupt mask.
> > > > > 4. Wait interrupt.
> > > > > <--- If status is cleared, interrupt does not occur.
> > > >
> > > > I understand. I'll add this explanation to the patch and apply it soon.
> > >
> > > Sorry, another question came up while applying:
> > >
> > > How can this interruption happen? The function is called in a
> > > spin_lock_irqsave protected area. Is this an RT_PREEMPT related issue?
> > > Am I missing something?
> >
> > Hi,
> >
> > any news on this one?
>
> Sorry, I seem to have dropped the ball here. I've (finally) forwarded
> your question on to the BSP team.
Thanks for your patience, I have a response from the BSP team:
rcar_i2c_start(), rcar_i2c_recv() and rcar_i2c_send() are called in a
spin_lock_irqsave protected area. Therefore, interruption and preemption
doesn't happen in these functions.
But I think the driver should work fine even if the CPU is very slow.
If above sequence 1 and 2 are slow, and if H/W is fast, there is a problem.
Since H/W is kicked by sequence 1 then the driver waits the change of status,
sequence 2 should be executed before sequence 1 even if the CPU is fast enough.
I think it is a custom of software.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-05-18 6:04 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-15 14:43 [PATCH/RFC] i2c: rcar: Fix order of restart and clear status Yoshihiro Kaneko
2015-02-23 13:07 ` Wolfram Sang
2015-03-04 4:08 ` Simon Horman
2015-03-06 22:05 ` Wolfram Sang
2015-03-07 10:33 ` Wolfram Sang
2015-03-27 13:10 ` Wolfram Sang
2015-03-30 0:15 ` Simon Horman
2015-05-18 6:04 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).