summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff')
-rw-r--r--meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff118
1 files changed, 118 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff b/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff
new file mode 100644
index 0000000000..6eb33f76b7
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff
@@ -0,0 +1,118 @@
1From linux-omap-owner@vger.kernel.org Tue Jul 15 21:23:13 2008
2Received: from localhost
3 ([127.0.0.1] helo=dominion ident=koen)
4 by dominion.dominion.void with esmtp (Exim 4.69)
5 (envelope-from <linux-omap-owner@vger.kernel.org>)
6 id 1KIq7E-0004FX-VS
7 for koen@localhost; Tue, 15 Jul 2008 21:23:13 +0200
8Received: from xs.service.utwente.nl [130.89.5.250]
9 by dominion with POP3 (fetchmail-6.3.6)
10 for <koen@localhost> (single-drop); Tue, 15 Jul 2008 21:23:12 +0200 (CEST)
11Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
12 Tue, 15 Jul 2008 21:01:02 +0200
13Received: from mx.utwente.nl ([130.89.2.12]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
14 Tue, 15 Jul 2008 21:01:01 +0200
15Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
16 by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m6FJ0qDf031889
17 for <k.kooi@student.utwente.nl>; Tue, 15 Jul 2008 21:00:52 +0200
18Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
19 id S1756776AbYGOTAV (ORCPT <rfc822;k.kooi@student.utwente.nl>);
20 Tue, 15 Jul 2008 15:00:21 -0400
21Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755065AbYGOTAV
22 (ORCPT <rfc822;linux-omap-outgoing>);
23 Tue, 15 Jul 2008 15:00:21 -0400
24Received: from utopia.booyaka.com ([72.9.107.138]:35569 "EHLO
25 utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
26 with ESMTP id S1756776AbYGOTAU (ORCPT
27 <rfc822;linux-omap@vger.kernel.org>); Tue, 15 Jul 2008 15:00:20 -0400
28Received: (qmail 2982 invoked by uid 526); 15 Jul 2008 19:00:18 -0000
29Date: Tue, 15 Jul 2008 13:00:18 -0600 (MDT)
30From: Paul Walmsley <paul@pwsan.com>
31To: linux-omap@vger.kernel.org
32Subject: [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and
33 omap_i2c_isr()
34Message-ID: <alpine.DEB.1.00.0807151259180.467@utopia.booyaka.com>
35User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
36MIME-Version: 1.0
37Content-Type: TEXT/PLAIN; charset=US-ASCII
38Sender: linux-omap-owner@vger.kernel.org
39Precedence: bulk
40List-ID: <linux-omap.vger.kernel.org>
41X-Mailing-List: linux-omap@vger.kernel.org
42X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
43X-UTwente-MailScanner: Found to be clean
44X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
45X-Spam-Status: No
46X-OriginalArrivalTime: 15 Jul 2008 19:01:01.0610 (UTC) FILETIME=[1FBA68A0:01C8E6AD]
47
48
49omap_i2c_idle() sets an internal flag, "dev->idle", instructing its
50ISR to decline interrupts. It sets this flag before it actually masks
51the interrupts on the I2C controller. This is problematic, since an
52I2C interrupt could arrive after dev->idle is set, but before the
53interrupt source is masked. When this happens, Linux disables the I2C
54controller's IRQ, causing all future transactions on the bus to fail.
55
56Symptoms, happening on about 7% of boots:
57
58 irq 56: nobody cared (try booting with the "irqpoll" option)
59 <warning traceback here>
60 Disabling IRQ #56
61 i2c_omap i2c_omap.1: controller timed out
62
63In omap_i2c_idle(), this patch sets dev->idle only after the interrupt
64mask write to the I2C controller has left the ARM write buffer.
65That's probably the major offender. For additional prophylaxis, in
66omap_i2c_unidle(), the patch clears the dev->idle flag before
67interrupts are enabled, rather than afterwards.
68
69The patch has survived twenty-two reboots on the 3430SDP here without
70wedging I2C1. Not absolutely dispositive, but promising!
71
72
73Signed-off-by: Paul Walmsley <paul@pwsan.com>
74---
75
76 drivers/i2c/busses/i2c-omap.c | 10 ++++++++--
77 1 files changed, 8 insertions(+), 2 deletions(-)
78
79diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
80index 55779f5..ed7e9ad 100644
81--- a/drivers/i2c/busses/i2c-omap.c
82+++ b/drivers/i2c/busses/i2c-omap.c
83@@ -209,22 +209,28 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
84 if (dev->iclk != NULL)
85 clk_enable(dev->iclk);
86 clk_enable(dev->fclk);
87+ dev->idle = 0;
88 if (dev->iestate)
89 omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
90- dev->idle = 0;
91 }
92
93 static void omap_i2c_idle(struct omap_i2c_dev *dev)
94 {
95 u16 iv;
96
97- dev->idle = 1;
98 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
99 omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
100 if (dev->rev1)
101 iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
102 else
103 omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
104+ /*
105+ * The wmb() is to ensure that the I2C interrupt mask write
106+ * reaches the I2C controller before the dev->idle store
107+ * occurs.
108+ */
109+ wmb();
110+ dev->idle = 1;
111 clk_disable(dev->fclk);
112 if (dev->iclk != NULL)
113 clk_disable(dev->iclk);
114--
115To unsubscribe from this list: send the line "unsubscribe linux-omap" in
116the body of a message to majordomo@vger.kernel.org
117More majordomo info at http://vger.kernel.org/majordomo-info.html
118