From: Tony Lindgren <tony@atomide.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-omap@vger.kernel.org
Subject: Re: [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and omap_i2c_isr()
Date: Mon, 4 Aug 2008 17:01:22 +0300 [thread overview]
Message-ID: <20080804140121.GF8885@atomide.com> (raw)
In-Reply-To: <alpine.DEB.1.00.0807151259180.467@utopia.booyaka.com>
* Paul Walmsley <paul@pwsan.com> [080715 22:04]:
>
> omap_i2c_idle() sets an internal flag, "dev->idle", instructing its
> ISR to decline interrupts. It sets this flag before it actually masks
> the interrupts on the I2C controller. This is problematic, since an
> I2C interrupt could arrive after dev->idle is set, but before the
> interrupt source is masked. When this happens, Linux disables the I2C
> controller's IRQ, causing all future transactions on the bus to fail.
>
> Symptoms, happening on about 7% of boots:
>
> irq 56: nobody cared (try booting with the "irqpoll" option)
> <warning traceback here>
> Disabling IRQ #56
> i2c_omap i2c_omap.1: controller timed out
>
> In omap_i2c_idle(), this patch sets dev->idle only after the interrupt
> mask write to the I2C controller has left the ARM write buffer.
> That's probably the major offender. For additional prophylaxis, in
> omap_i2c_unidle(), the patch clears the dev->idle flag before
> interrupts are enabled, rather than afterwards.
>
> The patch has survived twenty-two reboots on the 3430SDP here without
> wedging I2C1. Not absolutely dispositive, but promising!
Great, pushing today.
Tony
>
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
>
> drivers/i2c/busses/i2c-omap.c | 10 ++++++++--
> 1 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 55779f5..ed7e9ad 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -209,22 +209,28 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
> if (dev->iclk != NULL)
> clk_enable(dev->iclk);
> clk_enable(dev->fclk);
> + dev->idle = 0;
> if (dev->iestate)
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> - dev->idle = 0;
> }
>
> static void omap_i2c_idle(struct omap_i2c_dev *dev)
> {
> u16 iv;
>
> - dev->idle = 1;
> dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
> if (dev->rev1)
> iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
> else
> omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
> + /*
> + * The wmb() is to ensure that the I2C interrupt mask write
> + * reaches the I2C controller before the dev->idle store
> + * occurs.
> + */
> + wmb();
> + dev->idle = 1;
> clk_disable(dev->fclk);
> if (dev->iclk != NULL)
> clk_disable(dev->iclk);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
prev parent reply other threads:[~2008-08-04 14:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-15 19:00 [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and omap_i2c_isr() Paul Walmsley
2008-08-04 14:01 ` Tony Lindgren [this message]
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=20080804140121.GF8885@atomide.com \
--to=tony@atomide.com \
--cc=linux-omap@vger.kernel.org \
--cc=paul@pwsan.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.