linux-omap2 git: add patch to fix a race in i2c code
authorKoen Kooi <koen@openembedded.org>
Tue, 15 Jul 2008 19:53:31 +0000 (19:53 +0000)
committerKoen Kooi <koen@openembedded.org>
Tue, 15 Jul 2008 19:53:31 +0000 (19:53 +0000)
packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff [new file with mode: 0644]
packages/linux/linux-omap2_git.bb

diff --git a/packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff b/packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff
new file mode 100644 (file)
index 0000000..6eb33f7
--- /dev/null
@@ -0,0 +1,118 @@
+From linux-omap-owner@vger.kernel.org Tue Jul 15 21:23:13 2008
+Received: from localhost
+       ([127.0.0.1] helo=dominion ident=koen)
+       by dominion.dominion.void with esmtp (Exim 4.69)
+       (envelope-from <linux-omap-owner@vger.kernel.org>)
+       id 1KIq7E-0004FX-VS
+       for koen@localhost; Tue, 15 Jul 2008 21:23:13 +0200
+Received: from xs.service.utwente.nl [130.89.5.250]
+       by dominion with POP3 (fetchmail-6.3.6)
+       for <koen@localhost> (single-drop); Tue, 15 Jul 2008 21:23:12 +0200 (CEST)
+Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
+        Tue, 15 Jul 2008 21:01:02 +0200
+Received: from mx.utwente.nl ([130.89.2.12]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
+        Tue, 15 Jul 2008 21:01:01 +0200
+Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
+          by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m6FJ0qDf031889
+          for <k.kooi@student.utwente.nl>; Tue, 15 Jul 2008 21:00:52 +0200
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+       id S1756776AbYGOTAV (ORCPT <rfc822;k.kooi@student.utwente.nl>);
+       Tue, 15 Jul 2008 15:00:21 -0400
+Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755065AbYGOTAV
+       (ORCPT <rfc822;linux-omap-outgoing>);
+       Tue, 15 Jul 2008 15:00:21 -0400
+Received: from utopia.booyaka.com ([72.9.107.138]:35569 "EHLO
+       utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
+       with ESMTP id S1756776AbYGOTAU (ORCPT
+       <rfc822;linux-omap@vger.kernel.org>); Tue, 15 Jul 2008 15:00:20 -0400
+Received: (qmail 2982 invoked by uid 526); 15 Jul 2008 19:00:18 -0000
+Date:  Tue, 15 Jul 2008 13:00:18 -0600 (MDT)
+From: Paul Walmsley <paul@pwsan.com>
+To: linux-omap@vger.kernel.org
+Subject: [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and
+ omap_i2c_isr()
+Message-ID: <alpine.DEB.1.00.0807151259180.467@utopia.booyaka.com>
+User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Sender: linux-omap-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <linux-omap.vger.kernel.org>
+X-Mailing-List:        linux-omap@vger.kernel.org
+X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
+X-UTwente-MailScanner: Found to be clean
+X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
+X-Spam-Status: No
+X-OriginalArrivalTime: 15 Jul 2008 19:01:01.0610 (UTC) FILETIME=[1FBA68A0:01C8E6AD]
+
+
+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!
+
+
+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
+
index 53bcd29..800a0eb 100644 (file)
@@ -5,7 +5,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git/${MA
 SRCREV = "7786cd7a00ae0b18923185789380a88052f4eee7"
 
 PV = "2.6.25+2.6.26-rc9+${PR}+git${SRCREV}"
-PR = "r44"
+PR = "r45"
 
 SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
           file://defconfig"
@@ -30,6 +30,7 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
            file://07-set-burst-size.diff;patch=1 \
            file://cache-display-fix.patch;patch=1 \
            file://serialfix.diff;patch=1 \
+           file://i2c-omap-race-fix.diff;patch=1 \
 "
 
 SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \