summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch303
1 files changed, 303 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch b/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch
new file mode 100644
index 0000000000..02a72ed9df
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/TWL4030-05.patch
@@ -0,0 +1,303 @@
1TWL4030: use *_SIH_CTRL.COR bit to determine whether to read or write ISR to clear
2
3From: Paul Walmsley <paul@pwsan.com>
4
5TWL4030 interrupt status register bits can be cleared in one of two ways:
6either by reading from the register, or by writing a 1 to the
7appropriate bit(s) in the register. This behavior can be altered at any
8time by the <twlmodule>_SIH_CTRL.COR register bit ("clear-on-read").
9
10The TWL4030 TRM is deeply confused as to whether COR=1 means that the
11registers are cleared on reads, or cleared on writes. Peter De
12Schrijver <peter.de-schrijver> confirms that COR=1 means that the registers
13are cleared on read.
14
15So, for each TWL4030 SIH, check the value of the *_SIH_CTRL.COR bit, and if
16it is 1, use reads to clear the ISRs; if it is 0, use writes.
17
18Also, use WARN_ON() to warn if the read/write failed, and don't skip
19the rest of the initialization on failure either.
20
21Thanks to Peter for his help with this patch.
22
23
24Signed-off-by: Paul Walmsley <paul@pwsan.com>
25---
26
27 drivers/i2c/chips/twl4030-core.c | 183 ++++++++++++++++++++++----------------
28 1 files changed, 106 insertions(+), 77 deletions(-)
29
30diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
31index 9d93524..eae0634 100644
32--- a/drivers/i2c/chips/twl4030-core.c
33+++ b/drivers/i2c/chips/twl4030-core.c
34@@ -133,6 +133,16 @@
35 /* on I2C-1 for 2430SDP */
36 #define CONFIG_I2C_TWL4030_ID 1
37
38+/* SIH_CTRL registers */
39+#define TWL4030_INT_PWR_SIH_CTRL 0x07
40+#define TWL4030_INTERRUPTS_BCISIHCTRL 0x0d
41+#define TWL4030_MADC_MADC_SIH_CTRL 0x67
42+#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
43+#define TWL4030_GPIO_GPIO_SIH_CTRL 0x2d
44+
45+#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
46+
47+
48 /* Helper functions */
49 static int
50 twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid);
51@@ -712,13 +722,61 @@ static int power_companion_init(void)
52 return e;
53 }
54
55+/**
56+ * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
57+ * @mod_no: TWL4030 module number
58+ * @reg: register index to clear
59+ * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0)
60+ *
61+ * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt
62+ * status register to ensure that any prior interrupts are cleared.
63+ * Returns the status from the I2C read operation.
64+ */
65+static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor)
66+{
67+ u8 tmp;
68+
69+ return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) :
70+ twl4030_i2c_write_u8(mod_no, 0xff, reg);
71+}
72+
73+/**
74+ * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes?
75+ * @mod_no: TWL4030 module number
76+ * @reg: register index to clear
77+ *
78+ * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for
79+ * the specified TWL module are cleared by reads, or 0 if cleared by
80+ * writes.
81+ */
82+static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
83+{
84+ u8 tmp = 0;
85+
86+ WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0);
87+
88+ tmp &= TWL4030_SIH_CTRL_COR_MASK;
89+ tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK);
90+
91+ return tmp;
92+}
93+
94 static void twl_init_irq(void)
95 {
96 int i = 0;
97 int res = 0;
98+ int cor;
99 char *msg = "Unable to register interrupt subsystem";
100 unsigned int irq_num;
101
102+ /*
103+ * For each TWL4030 module with ISR/IMR registers, mask all
104+ * interrupts and then clear any existing interrupt status bits,
105+ * since we initially do not have any TWL4030 module interrupt
106+ * handlers present.
107+ */
108+
109+
110 /* PWR_IMR1 */
111 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
112 if (res < 0) {
113@@ -734,20 +792,18 @@ static void twl_init_irq(void)
114 }
115
116 /* Clear off any other pending interrupts on power */
117+
118+ /* Are PWR interrupt status bits cleared by reads or writes? */
119+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
120+ TWL4030_INT_PWR_SIH_CTRL);
121+ WARN_ON(cor < 0);
122+
123 /* PWR_ISR1 */
124- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
125- if (res < 0) {
126- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
127- return;
128- }
129+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00, cor) < 0);
130
131 /* PWR_ISR2 */
132- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
133- if (res < 0) {
134- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
135- return;
136- }
137- /* POWER HACK (END) */
138+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02, cor) < 0);
139+
140 /* Slave address 0x4A */
141
142 /* BCIIMR1A */
143@@ -778,33 +834,22 @@ static void twl_init_irq(void)
144 return;
145 }
146
147+ /* Are BCI interrupt status bits cleared by reads or writes? */
148+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
149+ TWL4030_INTERRUPTS_BCISIHCTRL);
150+ WARN_ON(cor < 0);
151+
152 /* BCIISR1A */
153- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
154- if (res < 0) {
155- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
156- return;
157- }
158+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0, cor) < 0);
159
160 /* BCIISR2A */
161- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
162- if (res < 0) {
163- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
164- return;
165- }
166+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1, cor) < 0);
167
168 /* BCIISR1B */
169- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
170- if (res < 0) {
171- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
172- return;
173- }
174+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4, cor) < 0);
175
176 /* BCIISR2B */
177- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
178- if (res < 0) {
179- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
180- return;
181- }
182+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5, cor) < 0);
183
184 /* MAD C */
185 /* MADC_IMR1 */
186@@ -821,19 +866,16 @@ static void twl_init_irq(void)
187 return;
188 }
189
190+ /* Are MADC interrupt status bits cleared by reads or writes? */
191+ cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
192+ TWL4030_MADC_MADC_SIH_CTRL);
193+ WARN_ON(cor < 0);
194+
195 /* MADC_ISR1 */
196- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
197- if (res < 0) {
198- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
199- return;
200- }
201+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61, cor) < 0);
202
203 /* MADC_ISR2 */
204- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
205- if (res < 0) {
206- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
207- return;
208- }
209+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63, cor) < 0);
210
211 /* key Pad */
212 /* KEYPAD - IMR1 */
213@@ -842,12 +884,15 @@ static void twl_init_irq(void)
214 pr_err("%s[%d][%d]\n", msg, res, __LINE__);
215 return;
216 }
217- {
218- u8 clear;
219- /* Clear ISR */
220- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
221- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
222- }
223+
224+ /* Are keypad interrupt status bits cleared by reads or writes? */
225+ cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
226+ TWL4030_KEYPAD_KEYP_SIH_CTRL);
227+ WARN_ON(cor < 0);
228+
229+ /* KEYPAD - ISR1 */
230+ /* XXX does this still need to be done twice for some reason? */
231+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
232
233 /* KEYPAD - IMR2 */
234 res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
235@@ -856,6 +901,9 @@ static void twl_init_irq(void)
236 return;
237 }
238
239+ /* KEYPAD - ISR2 */
240+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
241+
242 /* Slave address 0x49 */
243 /* GPIO_IMR1A */
244 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
245@@ -899,47 +947,28 @@ static void twl_init_irq(void)
246 return;
247 }
248
249+ /* Are GPIO interrupt status bits cleared by reads or writes? */
250+ cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
251+ TWL4030_GPIO_GPIO_SIH_CTRL);
252+ WARN_ON(cor < 0);
253+
254 /* GPIO_ISR1A */
255- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
256- if (res < 0) {
257- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
258- return;
259- }
260+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19, cor) < 0);
261
262 /* GPIO_ISR2A */
263- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
264- if (res < 0) {
265- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
266- return;
267- }
268+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a, cor) < 0);
269
270 /* GPIO_ISR3A */
271- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
272- if (res < 0) {
273- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
274- return;
275- }
276+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b, cor) < 0);
277
278 /* GPIO_ISR1B */
279- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
280- if (res < 0) {
281- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
282- return;
283- }
284+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f, cor) < 0);
285
286 /* GPIO_ISR2B */
287- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
288- if (res < 0) {
289- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
290- return;
291- }
292+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20, cor) < 0);
293
294 /* GPIO_ISR3B */
295- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
296- if (res < 0) {
297- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
298- return;
299- }
300+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21, cor) < 0);
301
302 /* install an irq handler for each of the PIH modules */
303 for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {