merge of '49118a4c6035353c0f8cf1aa30297dd36e43241f'
[vuplus_openembedded] / packages / linux / linux-omap2-git / beagleboard / TWL4030-05.patch
1 X-Mozilla-Status: 0001
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
5         morningsun.geekisp.com
6 X-Spam-Level: 
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
33 MIME-Version: 1.0
34 Content-Type: text/plain; charset="utf-8"
35 Content-Transfer-Encoding: 7bit
36 Sender: linux-omap-owner@vger.kernel.org
37 Precedence: bulk
38 List-ID: <linux-omap.vger.kernel.org>
39 X-Mailing-List: linux-omap@vger.kernel.org
40
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").
45
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.
49
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
53 either.
54
55 Signed-off-by: Paul Walmsley <paul@pwsan.com>
56 ---
57
58  drivers/i2c/chips/twl4030-core.c |  128 +++++++++++++++-----------------------
59  1 files changed, 51 insertions(+), 77 deletions(-)
60
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)
66         return e;
67  }
68  
69 +/**
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
73 + *
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.
78 + */
79 +static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg)
80 +{
81 +       int res;
82 +       u8 tmp;
83 +
84 +       res = twl4030_i2c_read_u8(mod_no, &tmp, reg);
85 +       if (res < 0)
86 +               return res;
87 +
88 +       return twl4030_i2c_write_u8(mod_no, 0xff, reg);
89 +}
90 +
91  static void twl_init_irq(void)
92  {
93         int     i = 0;
94 @@ -719,6 +741,13 @@ static void twl_init_irq(void)
95         char    *msg = "Unable to register interrupt subsystem";
96         unsigned int irq_num;
97  
98 +       /*
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.
103 +        */
104 +
105         /* PWR_IMR1 */
106         res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
107         if (res < 0) {
108 @@ -735,19 +764,11 @@ static void twl_init_irq(void)
109  
110         /* Clear off any other pending interrupts on power */
111         /* PWR_ISR1 */
112 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
113 -       if (res < 0) {
114 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
115 -               return;
116 -       }
117 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00) < 0);
118  
119         /* PWR_ISR2 */
120 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
121 -       if (res < 0) {
122 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
123 -               return;
124 -       }
125 -       /* POWER HACK (END) */
126 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02) < 0);
127 +
128         /* Slave address 0x4A */
129  
130         /* BCIIMR1A */
131 @@ -779,32 +800,16 @@ static void twl_init_irq(void)
132         }
133  
134         /* BCIISR1A */
135 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
136 -       if (res < 0) {
137 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
138 -               return;
139 -       }
140 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0) < 0);
141  
142         /* BCIISR2A */
143 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
144 -       if (res < 0) {
145 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
146 -               return;
147 -       }
148 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1) < 0);
149  
150         /* BCIISR1B */
151 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
152 -       if (res < 0) {
153 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
154 -               return;
155 -       }
156 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4) < 0);
157  
158         /* BCIISR2B */
159 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
160 -       if (res < 0) {
161 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
162 -               return;
163 -       }
164 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5) < 0);
165  
166         /* MAD C */
167         /* MADC_IMR1 */
168 @@ -822,18 +827,10 @@ static void twl_init_irq(void)
169         }
170  
171         /* MADC_ISR1 */
172 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
173 -       if (res < 0) {
174 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
175 -               return;
176 -       }
177 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61) < 0);
178  
179         /* MADC_ISR2 */
180 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
181 -       if (res < 0) {
182 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
183 -               return;
184 -       }
185 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63) < 0);
186  
187         /* key Pad */
188         /* KEYPAD - IMR1 */
189 @@ -842,12 +839,10 @@ static void twl_init_irq(void)
190                 pr_err("%s[%d][%d]\n", msg, res, __LINE__);
191                 return;
192         }
193 -       {
194 -               u8 clear;
195 -               /* Clear ISR */
196 -               twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
197 -               twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
198 -       }
199 +
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);
203  
204         /* KEYPAD - IMR2 */
205         res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
206 @@ -856,6 +851,9 @@ static void twl_init_irq(void)
207                 return;
208         }
209  
210 +       /* KEYPAD - ISR2 */
211 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13) < 0);
212 +
213         /* Slave address 0x49 */
214         /* GPIO_IMR1A */
215         res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
216 @@ -900,46 +898,22 @@ static void twl_init_irq(void)
217         }
218  
219         /* GPIO_ISR1A */
220 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
221 -       if (res < 0) {
222 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
223 -               return;
224 -       }
225 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19) < 0);
226  
227         /* GPIO_ISR2A */
228 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
229 -       if (res < 0) {
230 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
231 -               return;
232 -       }
233 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a) < 0);
234  
235         /* GPIO_ISR3A */
236 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
237 -       if (res < 0) {
238 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
239 -               return;
240 -       }
241 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b) < 0);
242  
243         /* GPIO_ISR1B */
244 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
245 -       if (res < 0) {
246 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
247 -               return;
248 -       }
249 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f) < 0);
250  
251         /* GPIO_ISR2B */
252 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
253 -       if (res < 0) {
254 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
255 -               return;
256 -       }
257 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20) < 0);
258  
259         /* GPIO_ISR3B */
260 -       res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
261 -       if (res < 0) {
262 -               pr_err("%s[%d][%d]\n", msg, res, __LINE__);
263 -               return;
264 -       }
265 +       WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21) < 0);
266  
267         /* install an irq handler for each of the PIH modules */
268         for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
269
270
271 --
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
275