Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify
[pandora-kernel.git] / drivers / mfd / max8998-irq.c
1 /*
2  * Interrupt controller support for MAX8998
3  *
4  * Copyright (C) 2010 Samsung Electronics Co.Ltd
5  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  *
12  */
13
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/mfd/max8998-private.h>
18
19 struct max8998_irq_data {
20         int reg;
21         int mask;
22 };
23
24 static struct max8998_irq_data max8998_irqs[] = {
25         [MAX8998_IRQ_DCINF] = {
26                 .reg = 1,
27                 .mask = MAX8998_IRQ_DCINF_MASK,
28         },
29         [MAX8998_IRQ_DCINR] = {
30                 .reg = 1,
31                 .mask = MAX8998_IRQ_DCINR_MASK,
32         },
33         [MAX8998_IRQ_JIGF] = {
34                 .reg = 1,
35                 .mask = MAX8998_IRQ_JIGF_MASK,
36         },
37         [MAX8998_IRQ_JIGR] = {
38                 .reg = 1,
39                 .mask = MAX8998_IRQ_JIGR_MASK,
40         },
41         [MAX8998_IRQ_PWRONF] = {
42                 .reg = 1,
43                 .mask = MAX8998_IRQ_PWRONF_MASK,
44         },
45         [MAX8998_IRQ_PWRONR] = {
46                 .reg = 1,
47                 .mask = MAX8998_IRQ_PWRONR_MASK,
48         },
49         [MAX8998_IRQ_WTSREVNT] = {
50                 .reg = 2,
51                 .mask = MAX8998_IRQ_WTSREVNT_MASK,
52         },
53         [MAX8998_IRQ_SMPLEVNT] = {
54                 .reg = 2,
55                 .mask = MAX8998_IRQ_SMPLEVNT_MASK,
56         },
57         [MAX8998_IRQ_ALARM1] = {
58                 .reg = 2,
59                 .mask = MAX8998_IRQ_ALARM1_MASK,
60         },
61         [MAX8998_IRQ_ALARM0] = {
62                 .reg = 2,
63                 .mask = MAX8998_IRQ_ALARM0_MASK,
64         },
65         [MAX8998_IRQ_ONKEY1S] = {
66                 .reg = 3,
67                 .mask = MAX8998_IRQ_ONKEY1S_MASK,
68         },
69         [MAX8998_IRQ_TOPOFFR] = {
70                 .reg = 3,
71                 .mask = MAX8998_IRQ_TOPOFFR_MASK,
72         },
73         [MAX8998_IRQ_DCINOVPR] = {
74                 .reg = 3,
75                 .mask = MAX8998_IRQ_DCINOVPR_MASK,
76         },
77         [MAX8998_IRQ_CHGRSTF] = {
78                 .reg = 3,
79                 .mask = MAX8998_IRQ_CHGRSTF_MASK,
80         },
81         [MAX8998_IRQ_DONER] = {
82                 .reg = 3,
83                 .mask = MAX8998_IRQ_DONER_MASK,
84         },
85         [MAX8998_IRQ_CHGFAULT] = {
86                 .reg = 3,
87                 .mask = MAX8998_IRQ_CHGFAULT_MASK,
88         },
89         [MAX8998_IRQ_LOBAT1] = {
90                 .reg = 4,
91                 .mask = MAX8998_IRQ_LOBAT1_MASK,
92         },
93         [MAX8998_IRQ_LOBAT2] = {
94                 .reg = 4,
95                 .mask = MAX8998_IRQ_LOBAT2_MASK,
96         },
97 };
98
99 static inline struct max8998_irq_data *
100 irq_to_max8998_irq(struct max8998_dev *max8998, int irq)
101 {
102         return &max8998_irqs[irq - max8998->irq_base];
103 }
104
105 static void max8998_irq_lock(unsigned int irq)
106 {
107         struct max8998_dev *max8998 = get_irq_chip_data(irq);
108
109         mutex_lock(&max8998->irqlock);
110 }
111
112 static void max8998_irq_sync_unlock(unsigned int irq)
113 {
114         struct max8998_dev *max8998 = get_irq_chip_data(irq);
115         int i;
116
117         for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) {
118                 /*
119                  * If there's been a change in the mask write it back
120                  * to the hardware.
121                  */
122                 if (max8998->irq_masks_cur[i] != max8998->irq_masks_cache[i]) {
123                         max8998->irq_masks_cache[i] = max8998->irq_masks_cur[i];
124                         max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i,
125                                         max8998->irq_masks_cur[i]);
126                 }
127         }
128
129         mutex_unlock(&max8998->irqlock);
130 }
131
132 static void max8998_irq_unmask(unsigned int irq)
133 {
134         struct max8998_dev *max8998 = get_irq_chip_data(irq);
135         struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq);
136
137         max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
138 }
139
140 static void max8998_irq_mask(unsigned int irq)
141 {
142         struct max8998_dev *max8998 = get_irq_chip_data(irq);
143         struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq);
144
145         max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
146 }
147
148 static struct irq_chip max8998_irq_chip = {
149         .name = "max8998",
150         .bus_lock = max8998_irq_lock,
151         .bus_sync_unlock = max8998_irq_sync_unlock,
152         .mask = max8998_irq_mask,
153         .unmask = max8998_irq_unmask,
154 };
155
156 static irqreturn_t max8998_irq_thread(int irq, void *data)
157 {
158         struct max8998_dev *max8998 = data;
159         u8 irq_reg[MAX8998_NUM_IRQ_REGS];
160         int ret;
161         int i;
162
163         ret = max8998_bulk_read(max8998->i2c, MAX8998_REG_IRQ1,
164                         MAX8998_NUM_IRQ_REGS, irq_reg);
165         if (ret < 0) {
166                 dev_err(max8998->dev, "Failed to read interrupt register: %d\n",
167                                 ret);
168                 return IRQ_NONE;
169         }
170
171         /* Apply masking */
172         for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++)
173                 irq_reg[i] &= ~max8998->irq_masks_cur[i];
174
175         /* Report */
176         for (i = 0; i < MAX8998_IRQ_NR; i++) {
177                 if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask)
178                         handle_nested_irq(max8998->irq_base + i);
179         }
180
181         return IRQ_HANDLED;
182 }
183
184 int max8998_irq_init(struct max8998_dev *max8998)
185 {
186         int i;
187         int cur_irq;
188         int ret;
189
190         if (!max8998->irq) {
191                 dev_warn(max8998->dev,
192                          "No interrupt specified, no interrupts\n");
193                 max8998->irq_base = 0;
194                 return 0;
195         }
196
197         if (!max8998->irq_base) {
198                 dev_err(max8998->dev,
199                         "No interrupt base specified, no interrupts\n");
200                 return 0;
201         }
202
203         mutex_init(&max8998->irqlock);
204
205         /* Mask the individual interrupt sources */
206         for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) {
207                 max8998->irq_masks_cur[i] = 0xff;
208                 max8998->irq_masks_cache[i] = 0xff;
209                 max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 0xff);
210         }
211
212         max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff);
213         max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff);
214
215         /* register with genirq */
216         for (i = 0; i < MAX8998_IRQ_NR; i++) {
217                 cur_irq = i + max8998->irq_base;
218                 set_irq_chip_data(cur_irq, max8998);
219                 set_irq_chip_and_handler(cur_irq, &max8998_irq_chip,
220                                          handle_edge_irq);
221                 set_irq_nested_thread(cur_irq, 1);
222 #ifdef CONFIG_ARM
223                 set_irq_flags(cur_irq, IRQF_VALID);
224 #else
225                 set_irq_noprobe(cur_irq);
226 #endif
227         }
228
229         ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread,
230                                    IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
231                                    "max8998-irq", max8998);
232         if (ret) {
233                 dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
234                         max8998->irq, ret);
235                 return ret;
236         }
237
238         if (!max8998->ono)
239                 return 0;
240
241         ret = request_threaded_irq(max8998->ono, NULL, max8998_irq_thread,
242                                    IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
243                                    IRQF_ONESHOT, "max8998-ono", max8998);
244         if (ret)
245                 dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
246                         max8998->ono, ret);
247
248         return 0;
249 }
250
251 void max8998_irq_exit(struct max8998_dev *max8998)
252 {
253         if (max8998->ono)
254                 free_irq(max8998->ono, max8998);
255
256         if (max8998->irq)
257                 free_irq(max8998->irq, max8998);
258 }