2 X-Mozilla-Status2: 00000000
3 Return-Path: <linux-omap-owner@vger.kernel.org>
4 X-Spam-Checker-Version: SpamAssassin 3.2.2 (2007-07-23) on
7 X-Spam-Status: No, score=-3.0 required=5.0 tests=AWL,DKIM_POLICY_SIGNSOME,
8 DK_POLICY_SIGNSOME,RCVD_IN_DNSWL_MED autolearn=ham version=3.2.2
9 Delivered-To: balister.org-philip@balister.org
10 Received: (qmail 11680 invoked by uid 1003); 18 Jul 2008 01:35:29 -0000
11 Received: from vger.kernel.org (209.132.176.167)
12 by mail.geekisp.com with SMTP; 18 Jul 2008 01:35:29 -0000
13 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
14 id S1755063AbYGRBf2 (ORCPT <rfc822;philip@balister.org>);
15 Thu, 17 Jul 2008 21:35:28 -0400
16 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754168AbYGRBf2
17 (ORCPT <rfc822;linux-omap-outgoing>);
18 Thu, 17 Jul 2008 21:35:28 -0400
19 Received: from utopia.booyaka.com ([72.9.107.138]:49365 "EHLO
20 utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
21 with ESMTP id S1755063AbYGRBfZ (ORCPT
22 <rfc822;linux-omap@vger.kernel.org>); Thu, 17 Jul 2008 21:35:25 -0400
23 Received: (qmail 13884 invoked by uid 526); 18 Jul 2008 01:35:23 -0000
24 MBOX-Line: From nobody Thu Jul 17 19:34:52 2008
25 From: Paul Walmsley <paul@pwsan.com>
26 Subject: [PATCH 5/9] TWL4030: read and write module ISRs to clear them at init
27 To: linux-omap@vger.kernel.org
28 Date: Thu, 17 Jul 2008 19:34:52 -0600
29 Message-ID: <20080718013451.18943.18579.stgit@localhost.localdomain>
30 In-Reply-To: <20080718013205.18943.34047.stgit@localhost.localdomain>
31 References: <20080718013205.18943.34047.stgit@localhost.localdomain>
32 User-Agent: StGIT/0.14.3.163.g06f9
34 Content-Type: text/plain; charset="utf-8"
35 Content-Transfer-Encoding: 7bit
36 Sender: linux-omap-owner@vger.kernel.org
38 List-ID: <linux-omap.vger.kernel.org>
39 X-Mailing-List: linux-omap@vger.kernel.org
41 TWL4030 interrupt status register bits can be cleared in one of two ways:
42 either by reading from the register, or by writing a 1 to the
43 appropriate bit(s) in the register. This behavior can be altered at any
44 time by the <twlmodule>_SIH_CTRL.COR register bit ("clear-on-read").
46 twl4030-core.c does not touch these *_SIH_CTRL registers during boot,
47 and the TWL4030 TRM is deeply confused as to whether COR=1 means that
48 the registers are cleared on reads, or cleared on writes.
50 So, take the cautious way out and both read from and write to the TWL4030
51 module ISRs to clear them at startup. Also, use WARN_ON() to warn if the
52 read/write failed, and don't skip the rest of the initialization on failure
55 Signed-off-by: Paul Walmsley <paul@pwsan.com>
58 drivers/i2c/chips/twl4030-core.c | 128 +++++++++++++++-----------------------
59 1 files changed, 51 insertions(+), 77 deletions(-)
61 diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
62 index 9d93524..615fb84 100644
63 --- a/drivers/i2c/chips/twl4030-core.c
64 +++ b/drivers/i2c/chips/twl4030-core.c
65 @@ -712,6 +712,28 @@ static int power_companion_init(void)
70 + * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
71 + * @mod_no: TWL4030 module number
72 + * @reg: register index to clear
74 + * Reads, then writes 0xff to a TWL4030 interrupt status register to ensure
75 + * that interrupts are cleared. The read + write is necessary since we
76 + * don't know whether the COR bit is set in <module>_SIH_CTRL. Returns
77 + * the status from the I2C read operation.
79 +static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg)
84 + res = twl4030_i2c_read_u8(mod_no, &tmp, reg);
88 + return twl4030_i2c_write_u8(mod_no, 0xff, reg);
91 static void twl_init_irq(void)
94 @@ -719,6 +741,13 @@ static void twl_init_irq(void)
95 char *msg = "Unable to register interrupt subsystem";
99 + * For each TWL4030 module with ISR/IMR registers, mask all
100 + * interrupts and then clear any existing interrupt status bits,
101 + * since we initially do not have any TWL4030 module interrupt
102 + * handlers present.
106 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
108 @@ -735,19 +764,11 @@ static void twl_init_irq(void)
110 /* Clear off any other pending interrupts on power */
112 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
114 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
117 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00) < 0);
120 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
122 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
125 - /* POWER HACK (END) */
126 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02) < 0);
128 /* Slave address 0x4A */
131 @@ -779,32 +800,16 @@ static void twl_init_irq(void)
135 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
137 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
140 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0) < 0);
143 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
145 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
148 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1) < 0);
151 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
153 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
156 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4) < 0);
159 - res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
161 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
164 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5) < 0);
168 @@ -822,18 +827,10 @@ static void twl_init_irq(void)
172 - res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
174 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
177 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61) < 0);
180 - res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
182 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
185 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63) < 0);
189 @@ -842,12 +839,10 @@ static void twl_init_irq(void)
190 pr_err("%s[%d][%d]\n", msg, res, __LINE__);
196 - twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
197 - twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
200 + /* KEYPAD - ISR1 */
201 + /* XXX does this still need to be done twice for some reason? */
202 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11) < 0);
205 res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
206 @@ -856,6 +851,9 @@ static void twl_init_irq(void)
210 + /* KEYPAD - ISR2 */
211 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13) < 0);
213 /* Slave address 0x49 */
215 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
216 @@ -900,46 +898,22 @@ static void twl_init_irq(void)
220 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
222 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
225 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19) < 0);
228 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
230 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
233 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a) < 0);
236 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
238 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
241 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b) < 0);
244 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
246 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
249 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f) < 0);
252 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
254 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
257 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20) < 0);
260 - res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
262 - pr_err("%s[%d][%d]\n", msg, res, __LINE__);
265 + WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21) < 0);
267 /* install an irq handler for each of the PIH modules */
268 for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
272 To unsubscribe from this list: send the line "unsubscribe linux-omap" in
273 the body of a message to majordomo@vger.kernel.org
274 More majordomo info at http://vger.kernel.org/majordomo-info.html