All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Voss, Nikolaus" <N.Voss@weinmann.de>
To: "'Hubert Feurstein'" <h.feurstein@gmail.com>
Cc: "'linux-arm-kernel@lists.infradead.org'" 
	<linux-arm-kernel@lists.infradead.org>,
	"'linux-kernel@vger.kernel.org'" <linux-kernel@vger.kernel.org>,
	"'linux-i2c@vger.kernel.org'" <linux-i2c@vger.kernel.org>,
	"'nicolas.ferre@atmel.com'" <nicolas.ferre@atmel.com>,
	"'ben-linux@fluff.org'" <ben-linux@fluff.org>,
	"'balbi@ti.com'" <balbi@ti.com>,
	"'rmallon@gmail.com'" <rmallon@gmail.com>
Subject: RE: [PATCH] i2c-at91: fix data-loss issue
Date: Mon, 16 Apr 2012 09:30:02 +0200	[thread overview]
Message-ID: <EF2E73589CA71846A15D0B2CDF79505D0905D5A1AA@wm021.weinmann.com> (raw)
In-Reply-To: <1334317476-10044-1-git-send-email-h.feurstein@gmail.com>

Hubert Feurstein wrote on 2012-04-13:
> In the interrupt handler both status-flags (TXCOMP and RXRDY) might be
> pending at the same time. In this case TXCOMP is handled but NOT RXRDY
> which causes a data-loss on the current transfer

Right, this is definitely a bug and must be corrected. Part of my
motivation for exclusively or-ing the irq bits was not reading/
writing beyond the buffer because of (still) pending bits despite
of an already finished transfer, so I gave TXCOMP the highest prio.

Because of other reasons, write_next_byte() already checks this and
does nothing if all data already has been written. My suggestion is
to have read_next_byte() do this check too, as I don't trust the
hardware to reset RXRDY _immediately_ after reading.

> @@ -161,18 +161,22 @@ static irqreturn_t atmel_twi_interrupt(int irq, void
> *dev_id)
>  {
>  	struct at91_twi_dev *dev = dev_id;
>  	const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
> -	const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +	unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +
> +	irqstatus &= (AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_TXCOMP);

The above line should be unnecessary as no more than those interrupts
are enabled anyway. Any special reason for this?
 
> +	if (!irqstatus)
> +		return IRQ_NONE;
> +
> +	if (irqstatus & AT91_TWI_RXRDY)
> +		at91_twi_read_next_byte(dev);
> +
> +	if (irqstatus & AT91_TWI_TXRDY)
> +		at91_twi_write_next_byte(dev);

I would like to exclusively or TXRDY and RXRDY as those really should
not be active at the same time. Keeps the decision tree lean ;-).

> @@ -189,6 +193,10 @@ static int
>  at91_do_twi_transfer(struct at91_twi_dev *dev) 	if (dev->msg->flags &
>  I2C_M_RD) { 		unsigned start_flags = AT91_TWI_START;
> +		/* clear any pending data */
> +		(void)at91_twi_read(dev, AT91_TWI_SR);
> +		(void)at91_twi_read(dev, AT91_TWI_RHR);

I would like to modify this, as this is a partial fix for the above bug
which should already be fully fixed by the modified isr.
I fear subtle data-loss if we make (partial) tabula rasa before each
transfer. I'd rather add an assertion to check if the corresponding
irqs are active as an indication for a driver/hw-bug.

I'll repost the driver with your fix on positive feedback from you.
Thanks for tracking this down.

Ben, is there any chance to get this driver into next?

Niko



WARNING: multiple messages have this Message-ID (diff)
From: "Voss, Nikolaus" <N.Voss@weinmann.de>
To: 'Hubert Feurstein' <h.feurstein@gmail.com>
Cc: "'rmallon@gmail.com'" <rmallon@gmail.com>,
	"'nicolas.ferre@atmel.com'" <nicolas.ferre@atmel.com>,
	"'linux-kernel@vger.kernel.org'" <linux-kernel@vger.kernel.org>,
	"'balbi@ti.com'" <balbi@ti.com>,
	"'linux-i2c@vger.kernel.org'" <linux-i2c@vger.kernel.org>,
	"'ben-linux@fluff.org'" <ben-linux@fluff.org>,
	"'linux-arm-kernel@lists.infradead.org'"
	<linux-arm-kernel@lists.infradead.org>
Subject: RE: [PATCH] i2c-at91: fix data-loss issue
Date: Mon, 16 Apr 2012 09:30:02 +0200	[thread overview]
Message-ID: <EF2E73589CA71846A15D0B2CDF79505D0905D5A1AA@wm021.weinmann.com> (raw)
In-Reply-To: <1334317476-10044-1-git-send-email-h.feurstein@gmail.com>

Hubert Feurstein wrote on 2012-04-13:
> In the interrupt handler both status-flags (TXCOMP and RXRDY) might be
> pending at the same time. In this case TXCOMP is handled but NOT RXRDY
> which causes a data-loss on the current transfer

Right, this is definitely a bug and must be corrected. Part of my
motivation for exclusively or-ing the irq bits was not reading/
writing beyond the buffer because of (still) pending bits despite
of an already finished transfer, so I gave TXCOMP the highest prio.

Because of other reasons, write_next_byte() already checks this and
does nothing if all data already has been written. My suggestion is
to have read_next_byte() do this check too, as I don't trust the
hardware to reset RXRDY _immediately_ after reading.

> @@ -161,18 +161,22 @@ static irqreturn_t atmel_twi_interrupt(int irq, void
> *dev_id)
>  {
>  	struct at91_twi_dev *dev = dev_id;
>  	const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
> -	const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +	unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +
> +	irqstatus &= (AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_TXCOMP);

The above line should be unnecessary as no more than those interrupts
are enabled anyway. Any special reason for this?
 
> +	if (!irqstatus)
> +		return IRQ_NONE;
> +
> +	if (irqstatus & AT91_TWI_RXRDY)
> +		at91_twi_read_next_byte(dev);
> +
> +	if (irqstatus & AT91_TWI_TXRDY)
> +		at91_twi_write_next_byte(dev);

I would like to exclusively or TXRDY and RXRDY as those really should
not be active at the same time. Keeps the decision tree lean ;-).

> @@ -189,6 +193,10 @@ static int
>  at91_do_twi_transfer(struct at91_twi_dev *dev) 	if (dev->msg->flags &
>  I2C_M_RD) { 		unsigned start_flags = AT91_TWI_START;
> +		/* clear any pending data */
> +		(void)at91_twi_read(dev, AT91_TWI_SR);
> +		(void)at91_twi_read(dev, AT91_TWI_RHR);

I would like to modify this, as this is a partial fix for the above bug
which should already be fully fixed by the modified isr.
I fear subtle data-loss if we make (partial) tabula rasa before each
transfer. I'd rather add an assertion to check if the corresponding
irqs are active as an indication for a driver/hw-bug.

I'll repost the driver with your fix on positive feedback from you.
Thanks for tracking this down.

Ben, is there any chance to get this driver into next?

Niko

WARNING: multiple messages have this Message-ID (diff)
From: N.Voss@weinmann.de (Voss, Nikolaus)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] i2c-at91: fix data-loss issue
Date: Mon, 16 Apr 2012 09:30:02 +0200	[thread overview]
Message-ID: <EF2E73589CA71846A15D0B2CDF79505D0905D5A1AA@wm021.weinmann.com> (raw)
In-Reply-To: <1334317476-10044-1-git-send-email-h.feurstein@gmail.com>

Hubert Feurstein wrote on 2012-04-13:
> In the interrupt handler both status-flags (TXCOMP and RXRDY) might be
> pending at the same time. In this case TXCOMP is handled but NOT RXRDY
> which causes a data-loss on the current transfer

Right, this is definitely a bug and must be corrected. Part of my
motivation for exclusively or-ing the irq bits was not reading/
writing beyond the buffer because of (still) pending bits despite
of an already finished transfer, so I gave TXCOMP the highest prio.

Because of other reasons, write_next_byte() already checks this and
does nothing if all data already has been written. My suggestion is
to have read_next_byte() do this check too, as I don't trust the
hardware to reset RXRDY _immediately_ after reading.

> @@ -161,18 +161,22 @@ static irqreturn_t atmel_twi_interrupt(int irq, void
> *dev_id)
>  {
>  	struct at91_twi_dev *dev = dev_id;
>  	const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
> -	const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +	unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
> +
> +	irqstatus &= (AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_TXCOMP);

The above line should be unnecessary as no more than those interrupts
are enabled anyway. Any special reason for this?
 
> +	if (!irqstatus)
> +		return IRQ_NONE;
> +
> +	if (irqstatus & AT91_TWI_RXRDY)
> +		at91_twi_read_next_byte(dev);
> +
> +	if (irqstatus & AT91_TWI_TXRDY)
> +		at91_twi_write_next_byte(dev);

I would like to exclusively or TXRDY and RXRDY as those really should
not be active at the same time. Keeps the decision tree lean ;-).

> @@ -189,6 +193,10 @@ static int
>  at91_do_twi_transfer(struct at91_twi_dev *dev) 	if (dev->msg->flags &
>  I2C_M_RD) { 		unsigned start_flags = AT91_TWI_START;
> +		/* clear any pending data */
> +		(void)at91_twi_read(dev, AT91_TWI_SR);
> +		(void)at91_twi_read(dev, AT91_TWI_RHR);

I would like to modify this, as this is a partial fix for the above bug
which should already be fully fixed by the modified isr.
I fear subtle data-loss if we make (partial) tabula rasa before each
transfer. I'd rather add an assertion to check if the corresponding
irqs are active as an indication for a driver/hw-bug.

I'll repost the driver with your fix on positive feedback from you.
Thanks for tracking this down.

Ben, is there any chance to get this driver into next?

Niko

  parent reply	other threads:[~2012-04-16  7:47 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-19 15:07 [PATCH v9 0/4] AT91: replace broken TWI driver i2c-at91.c Nikolaus Voss
2012-03-19 15:07 ` Nikolaus Voss
2011-11-08 10:49 ` [PATCH v9 1/4] drivers/i2c/busses/i2c-at91.c: remove broken driver Nikolaus Voss
2011-11-08 10:49   ` Nikolaus Voss
2011-11-08 10:49 ` [PATCH v9 3/4] drivers/i2c/busses/i2c-at91.c: add new driver Nikolaus Voss
2011-11-08 10:49   ` Nikolaus Voss
2012-04-13 10:17   ` Hubert Feurstein
2012-04-13 10:17     ` Hubert Feurstein
2012-04-13 10:17     ` Hubert Feurstein
2012-04-13 10:39     ` Felipe Balbi
2012-04-13 10:39       ` Felipe Balbi
2012-04-13 10:39       ` Felipe Balbi
2012-04-13 11:44       ` [PATCH] i2c-at91: fix data-loss issue Hubert Feurstein
2012-04-13 11:44         ` Hubert Feurstein
2012-04-13 11:44         ` Hubert Feurstein
2012-04-13 22:06         ` Ryan Mallon
2012-04-13 22:06           ` Ryan Mallon
2012-04-13 22:06           ` Ryan Mallon
2012-04-16  7:30         ` Voss, Nikolaus [this message]
2012-04-16  7:30           ` Voss, Nikolaus
2012-04-16  7:30           ` Voss, Nikolaus
2012-04-16  9:27           ` Hubert Feurstein
2012-04-16  9:27             ` Hubert Feurstein
2012-04-16  9:27             ` Hubert Feurstein
2012-04-18 14:39           ` Wolfram Sang
2012-04-18 14:39             ` Wolfram Sang
2012-04-18 14:39             ` Wolfram Sang
2012-04-21 19:33             ` Adrian Yanes
2012-04-23  5:39               ` Voss, Nikolaus
2012-04-23  5:39                 ` Voss, Nikolaus
2012-04-23  5:39                 ` Voss, Nikolaus
2012-04-23  6:24                 ` Adrian Yanes
2012-04-23  6:24                   ` Adrian Yanes
2012-04-23  6:24                   ` Adrian Yanes
2012-04-25  5:26                   ` Adrian Yanes
2011-11-08 11:09 ` [PATCH v9 2/4] Replace clk_lookup.con_id with clk_lookup.dev_id entries for twi clk Nikolaus Voss
2011-11-08 11:09   ` Nikolaus Voss
2011-11-08 11:11 ` [PATCH v9 4/4] G45 TWI: remove open drain setting for twi function gpios Nikolaus Voss
2011-11-08 11:11   ` Nikolaus Voss

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=EF2E73589CA71846A15D0B2CDF79505D0905D5A1AA@wm021.weinmann.com \
    --to=n.voss@weinmann.de \
    --cc=balbi@ti.com \
    --cc=ben-linux@fluff.org \
    --cc=h.feurstein@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nicolas.ferre@atmel.com \
    --cc=rmallon@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.