aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/sec-irq.c
diff options
context:
space:
mode:
authorSangbeom Kim <sbkim73@samsung.com>2012-07-11 08:08:11 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-16 08:31:59 -0400
commit6445b84abf91549d8568fb5d9155447e6dba86cc (patch)
tree07b8341d4360f80630146cb21c171d6e518202d9 /drivers/mfd/sec-irq.c
parent9b6d1343068d87f06c8dabf6628a30ea38082eb0 (diff)
mfd: Add s2mps11 irq driver
This patch support irq handling driver for s2mps11. As this patch use regmap_irq, s5m8767 and s5m8763 are modified with regmap_irq. Signed-off-by: Sangbeom Kim <sbkim73@samsung.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/sec-irq.c')
-rw-r--r--drivers/mfd/sec-irq.c477
1 files changed, 148 insertions, 329 deletions
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c
index da5ec5b2ecce..c901fa50fea1 100644
--- a/drivers/mfd/sec-irq.c
+++ b/drivers/mfd/sec-irq.c
@@ -14,351 +14,260 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/regmap.h>
18
17#include <linux/mfd/samsung/core.h> 19#include <linux/mfd/samsung/core.h>
18#include <linux/mfd/samsung/irq.h> 20#include <linux/mfd/samsung/irq.h>
21#include <linux/mfd/samsung/s2mps11.h>
19#include <linux/mfd/samsung/s5m8763.h> 22#include <linux/mfd/samsung/s5m8763.h>
20#include <linux/mfd/samsung/s5m8767.h> 23#include <linux/mfd/samsung/s5m8767.h>
21 24
22struct sec_irq_data { 25static struct regmap_irq s2mps11_irqs[] = {
23 int reg; 26 [S2MPS11_IRQ_PWRONF] = {
24 int mask; 27 .reg_offset = 1,
28 .mask = S2MPS11_IRQ_PWRONF_MASK,
29 },
30 [S2MPS11_IRQ_PWRONR] = {
31 .reg_offset = 1,
32 .mask = S2MPS11_IRQ_PWRONR_MASK,
33 },
34 [S2MPS11_IRQ_JIGONBF] = {
35 .reg_offset = 1,
36 .mask = S2MPS11_IRQ_JIGONBF_MASK,
37 },
38 [S2MPS11_IRQ_JIGONBR] = {
39 .reg_offset = 1,
40 .mask = S2MPS11_IRQ_JIGONBR_MASK,
41 },
42 [S2MPS11_IRQ_ACOKBF] = {
43 .reg_offset = 1,
44 .mask = S2MPS11_IRQ_ACOKBF_MASK,
45 },
46 [S2MPS11_IRQ_ACOKBR] = {
47 .reg_offset = 1,
48 .mask = S2MPS11_IRQ_ACOKBR_MASK,
49 },
50 [S2MPS11_IRQ_PWRON1S] = {
51 .reg_offset = 1,
52 .mask = S2MPS11_IRQ_PWRON1S_MASK,
53 },
54 [S2MPS11_IRQ_MRB] = {
55 .reg_offset = 1,
56 .mask = S2MPS11_IRQ_MRB_MASK,
57 },
58 [S2MPS11_IRQ_RTC60S] = {
59 .reg_offset = 2,
60 .mask = S2MPS11_IRQ_RTC60S_MASK,
61 },
62 [S2MPS11_IRQ_RTCA1] = {
63 .reg_offset = 2,
64 .mask = S2MPS11_IRQ_RTCA1_MASK,
65 },
66 [S2MPS11_IRQ_RTCA2] = {
67 .reg_offset = 2,
68 .mask = S2MPS11_IRQ_RTCA2_MASK,
69 },
70 [S2MPS11_IRQ_SMPL] = {
71 .reg_offset = 2,
72 .mask = S2MPS11_IRQ_SMPL_MASK,
73 },
74 [S2MPS11_IRQ_RTC1S] = {
75 .reg_offset = 2,
76 .mask = S2MPS11_IRQ_RTC1S_MASK,
77 },
78 [S2MPS11_IRQ_WTSR] = {
79 .reg_offset = 2,
80 .mask = S2MPS11_IRQ_WTSR_MASK,
81 },
82 [S2MPS11_IRQ_INT120C] = {
83 .reg_offset = 3,
84 .mask = S2MPS11_IRQ_INT120C_MASK,
85 },
86 [S2MPS11_IRQ_INT140C] = {
87 .reg_offset = 3,
88 .mask = S2MPS11_IRQ_INT140C_MASK,
89 },
25}; 90};
26 91
27static struct sec_irq_data s5m8767_irqs[] = { 92
93static struct regmap_irq s5m8767_irqs[] = {
28 [S5M8767_IRQ_PWRR] = { 94 [S5M8767_IRQ_PWRR] = {
29 .reg = 1, 95 .reg_offset = 1,
30 .mask = S5M8767_IRQ_PWRR_MASK, 96 .mask = S5M8767_IRQ_PWRR_MASK,
31 }, 97 },
32 [S5M8767_IRQ_PWRF] = { 98 [S5M8767_IRQ_PWRF] = {
33 .reg = 1, 99 .reg_offset = 1,
34 .mask = S5M8767_IRQ_PWRF_MASK, 100 .mask = S5M8767_IRQ_PWRF_MASK,
35 }, 101 },
36 [S5M8767_IRQ_PWR1S] = { 102 [S5M8767_IRQ_PWR1S] = {
37 .reg = 1, 103 .reg_offset = 1,
38 .mask = S5M8767_IRQ_PWR1S_MASK, 104 .mask = S5M8767_IRQ_PWR1S_MASK,
39 }, 105 },
40 [S5M8767_IRQ_JIGR] = { 106 [S5M8767_IRQ_JIGR] = {
41 .reg = 1, 107 .reg_offset = 1,
42 .mask = S5M8767_IRQ_JIGR_MASK, 108 .mask = S5M8767_IRQ_JIGR_MASK,
43 }, 109 },
44 [S5M8767_IRQ_JIGF] = { 110 [S5M8767_IRQ_JIGF] = {
45 .reg = 1, 111 .reg_offset = 1,
46 .mask = S5M8767_IRQ_JIGF_MASK, 112 .mask = S5M8767_IRQ_JIGF_MASK,
47 }, 113 },
48 [S5M8767_IRQ_LOWBAT2] = { 114 [S5M8767_IRQ_LOWBAT2] = {
49 .reg = 1, 115 .reg_offset = 1,
50 .mask = S5M8767_IRQ_LOWBAT2_MASK, 116 .mask = S5M8767_IRQ_LOWBAT2_MASK,
51 }, 117 },
52 [S5M8767_IRQ_LOWBAT1] = { 118 [S5M8767_IRQ_LOWBAT1] = {
53 .reg = 1, 119 .reg_offset = 1,
54 .mask = S5M8767_IRQ_LOWBAT1_MASK, 120 .mask = S5M8767_IRQ_LOWBAT1_MASK,
55 }, 121 },
56 [S5M8767_IRQ_MRB] = { 122 [S5M8767_IRQ_MRB] = {
57 .reg = 2, 123 .reg_offset = 2,
58 .mask = S5M8767_IRQ_MRB_MASK, 124 .mask = S5M8767_IRQ_MRB_MASK,
59 }, 125 },
60 [S5M8767_IRQ_DVSOK2] = { 126 [S5M8767_IRQ_DVSOK2] = {
61 .reg = 2, 127 .reg_offset = 2,
62 .mask = S5M8767_IRQ_DVSOK2_MASK, 128 .mask = S5M8767_IRQ_DVSOK2_MASK,
63 }, 129 },
64 [S5M8767_IRQ_DVSOK3] = { 130 [S5M8767_IRQ_DVSOK3] = {
65 .reg = 2, 131 .reg_offset = 2,
66 .mask = S5M8767_IRQ_DVSOK3_MASK, 132 .mask = S5M8767_IRQ_DVSOK3_MASK,
67 }, 133 },
68 [S5M8767_IRQ_DVSOK4] = { 134 [S5M8767_IRQ_DVSOK4] = {
69 .reg = 2, 135 .reg_offset = 2,
70 .mask = S5M8767_IRQ_DVSOK4_MASK, 136 .mask = S5M8767_IRQ_DVSOK4_MASK,
71 }, 137 },
72 [S5M8767_IRQ_RTC60S] = { 138 [S5M8767_IRQ_RTC60S] = {
73 .reg = 3, 139 .reg_offset = 3,
74 .mask = S5M8767_IRQ_RTC60S_MASK, 140 .mask = S5M8767_IRQ_RTC60S_MASK,
75 }, 141 },
76 [S5M8767_IRQ_RTCA1] = { 142 [S5M8767_IRQ_RTCA1] = {
77 .reg = 3, 143 .reg_offset = 3,
78 .mask = S5M8767_IRQ_RTCA1_MASK, 144 .mask = S5M8767_IRQ_RTCA1_MASK,
79 }, 145 },
80 [S5M8767_IRQ_RTCA2] = { 146 [S5M8767_IRQ_RTCA2] = {
81 .reg = 3, 147 .reg_offset = 3,
82 .mask = S5M8767_IRQ_RTCA2_MASK, 148 .mask = S5M8767_IRQ_RTCA2_MASK,
83 }, 149 },
84 [S5M8767_IRQ_SMPL] = { 150 [S5M8767_IRQ_SMPL] = {
85 .reg = 3, 151 .reg_offset = 3,
86 .mask = S5M8767_IRQ_SMPL_MASK, 152 .mask = S5M8767_IRQ_SMPL_MASK,
87 }, 153 },
88 [S5M8767_IRQ_RTC1S] = { 154 [S5M8767_IRQ_RTC1S] = {
89 .reg = 3, 155 .reg_offset = 3,
90 .mask = S5M8767_IRQ_RTC1S_MASK, 156 .mask = S5M8767_IRQ_RTC1S_MASK,
91 }, 157 },
92 [S5M8767_IRQ_WTSR] = { 158 [S5M8767_IRQ_WTSR] = {
93 .reg = 3, 159 .reg_offset = 3,
94 .mask = S5M8767_IRQ_WTSR_MASK, 160 .mask = S5M8767_IRQ_WTSR_MASK,
95 }, 161 },
96}; 162};
97 163
98static struct sec_irq_data s5m8763_irqs[] = { 164static struct regmap_irq s5m8763_irqs[] = {
99 [S5M8763_IRQ_DCINF] = { 165 [S5M8763_IRQ_DCINF] = {
100 .reg = 1, 166 .reg_offset = 1,
101 .mask = S5M8763_IRQ_DCINF_MASK, 167 .mask = S5M8763_IRQ_DCINF_MASK,
102 }, 168 },
103 [S5M8763_IRQ_DCINR] = { 169 [S5M8763_IRQ_DCINR] = {
104 .reg = 1, 170 .reg_offset = 1,
105 .mask = S5M8763_IRQ_DCINR_MASK, 171 .mask = S5M8763_IRQ_DCINR_MASK,
106 }, 172 },
107 [S5M8763_IRQ_JIGF] = { 173 [S5M8763_IRQ_JIGF] = {
108 .reg = 1, 174 .reg_offset = 1,
109 .mask = S5M8763_IRQ_JIGF_MASK, 175 .mask = S5M8763_IRQ_JIGF_MASK,
110 }, 176 },
111 [S5M8763_IRQ_JIGR] = { 177 [S5M8763_IRQ_JIGR] = {
112 .reg = 1, 178 .reg_offset = 1,
113 .mask = S5M8763_IRQ_JIGR_MASK, 179 .mask = S5M8763_IRQ_JIGR_MASK,
114 }, 180 },
115 [S5M8763_IRQ_PWRONF] = { 181 [S5M8763_IRQ_PWRONF] = {
116 .reg = 1, 182 .reg_offset = 1,
117 .mask = S5M8763_IRQ_PWRONF_MASK, 183 .mask = S5M8763_IRQ_PWRONF_MASK,
118 }, 184 },
119 [S5M8763_IRQ_PWRONR] = { 185 [S5M8763_IRQ_PWRONR] = {
120 .reg = 1, 186 .reg_offset = 1,
121 .mask = S5M8763_IRQ_PWRONR_MASK, 187 .mask = S5M8763_IRQ_PWRONR_MASK,
122 }, 188 },
123 [S5M8763_IRQ_WTSREVNT] = { 189 [S5M8763_IRQ_WTSREVNT] = {
124 .reg = 2, 190 .reg_offset = 2,
125 .mask = S5M8763_IRQ_WTSREVNT_MASK, 191 .mask = S5M8763_IRQ_WTSREVNT_MASK,
126 }, 192 },
127 [S5M8763_IRQ_SMPLEVNT] = { 193 [S5M8763_IRQ_SMPLEVNT] = {
128 .reg = 2, 194 .reg_offset = 2,
129 .mask = S5M8763_IRQ_SMPLEVNT_MASK, 195 .mask = S5M8763_IRQ_SMPLEVNT_MASK,
130 }, 196 },
131 [S5M8763_IRQ_ALARM1] = { 197 [S5M8763_IRQ_ALARM1] = {
132 .reg = 2, 198 .reg_offset = 2,
133 .mask = S5M8763_IRQ_ALARM1_MASK, 199 .mask = S5M8763_IRQ_ALARM1_MASK,
134 }, 200 },
135 [S5M8763_IRQ_ALARM0] = { 201 [S5M8763_IRQ_ALARM0] = {
136 .reg = 2, 202 .reg_offset = 2,
137 .mask = S5M8763_IRQ_ALARM0_MASK, 203 .mask = S5M8763_IRQ_ALARM0_MASK,
138 }, 204 },
139 [S5M8763_IRQ_ONKEY1S] = { 205 [S5M8763_IRQ_ONKEY1S] = {
140 .reg = 3, 206 .reg_offset = 3,
141 .mask = S5M8763_IRQ_ONKEY1S_MASK, 207 .mask = S5M8763_IRQ_ONKEY1S_MASK,
142 }, 208 },
143 [S5M8763_IRQ_TOPOFFR] = { 209 [S5M8763_IRQ_TOPOFFR] = {
144 .reg = 3, 210 .reg_offset = 3,
145 .mask = S5M8763_IRQ_TOPOFFR_MASK, 211 .mask = S5M8763_IRQ_TOPOFFR_MASK,
146 }, 212 },
147 [S5M8763_IRQ_DCINOVPR] = { 213 [S5M8763_IRQ_DCINOVPR] = {
148 .reg = 3, 214 .reg_offset = 3,
149 .mask = S5M8763_IRQ_DCINOVPR_MASK, 215 .mask = S5M8763_IRQ_DCINOVPR_MASK,
150 }, 216 },
151 [S5M8763_IRQ_CHGRSTF] = { 217 [S5M8763_IRQ_CHGRSTF] = {
152 .reg = 3, 218 .reg_offset = 3,
153 .mask = S5M8763_IRQ_CHGRSTF_MASK, 219 .mask = S5M8763_IRQ_CHGRSTF_MASK,
154 }, 220 },
155 [S5M8763_IRQ_DONER] = { 221 [S5M8763_IRQ_DONER] = {
156 .reg = 3, 222 .reg_offset = 3,
157 .mask = S5M8763_IRQ_DONER_MASK, 223 .mask = S5M8763_IRQ_DONER_MASK,
158 }, 224 },
159 [S5M8763_IRQ_CHGFAULT] = { 225 [S5M8763_IRQ_CHGFAULT] = {
160 .reg = 3, 226 .reg_offset = 3,
161 .mask = S5M8763_IRQ_CHGFAULT_MASK, 227 .mask = S5M8763_IRQ_CHGFAULT_MASK,
162 }, 228 },
163 [S5M8763_IRQ_LOBAT1] = { 229 [S5M8763_IRQ_LOBAT1] = {
164 .reg = 4, 230 .reg_offset = 4,
165 .mask = S5M8763_IRQ_LOBAT1_MASK, 231 .mask = S5M8763_IRQ_LOBAT1_MASK,
166 }, 232 },
167 [S5M8763_IRQ_LOBAT2] = { 233 [S5M8763_IRQ_LOBAT2] = {
168 .reg = 4, 234 .reg_offset = 4,
169 .mask = S5M8763_IRQ_LOBAT2_MASK, 235 .mask = S5M8763_IRQ_LOBAT2_MASK,
170 }, 236 },
171}; 237};
172 238
173static inline struct sec_irq_data * 239static struct regmap_irq_chip s2mps11_irq_chip = {
174irq_to_s5m8767_irq(struct sec_pmic_dev *sec_pmic, int irq) 240 .name = "s2mps11",
175{ 241 .irqs = s2mps11_irqs,
176 return &s5m8767_irqs[irq - sec_pmic->irq_base]; 242 .num_irqs = ARRAY_SIZE(s2mps11_irqs),
177} 243 .num_regs = 3,
178 244 .status_base = S2MPS11_REG_INT1,
179static void s5m8767_irq_lock(struct irq_data *data) 245 .mask_base = S2MPS11_REG_INT1M,
180{ 246 .ack_base = S2MPS11_REG_INT1,
181 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 247};
182
183 mutex_lock(&sec_pmic->irqlock);
184}
185
186static void s5m8767_irq_sync_unlock(struct irq_data *data)
187{
188 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
189 int i;
190
191 for (i = 0; i < ARRAY_SIZE(sec_pmic->irq_masks_cur); i++) {
192 if (sec_pmic->irq_masks_cur[i] != sec_pmic->irq_masks_cache[i]) {
193 sec_pmic->irq_masks_cache[i] = sec_pmic->irq_masks_cur[i];
194 sec_reg_write(sec_pmic, S5M8767_REG_INT1M + i,
195 sec_pmic->irq_masks_cur[i]);
196 }
197 }
198
199 mutex_unlock(&sec_pmic->irqlock);
200}
201
202static void s5m8767_irq_unmask(struct irq_data *data)
203{
204 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
205 struct sec_irq_data *irq_data = irq_to_s5m8767_irq(sec_pmic,
206 data->irq);
207
208 sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
209}
210
211static void s5m8767_irq_mask(struct irq_data *data)
212{
213 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
214 struct sec_irq_data *irq_data = irq_to_s5m8767_irq(sec_pmic,
215 data->irq);
216
217 sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
218}
219 248
220static struct irq_chip s5m8767_irq_chip = { 249static struct regmap_irq_chip s5m8767_irq_chip = {
221 .name = "s5m8767", 250 .name = "s5m8767",
222 .irq_bus_lock = s5m8767_irq_lock, 251 .irqs = s5m8767_irqs,
223 .irq_bus_sync_unlock = s5m8767_irq_sync_unlock, 252 .num_irqs = ARRAY_SIZE(s5m8767_irqs),
224 .irq_mask = s5m8767_irq_mask, 253 .num_regs = 3,
225 .irq_unmask = s5m8767_irq_unmask, 254 .status_base = S5M8767_REG_INT1,
255 .mask_base = S5M8767_REG_INT1M,
256 .ack_base = S5M8767_REG_INT1,
226}; 257};
227 258
228static inline struct sec_irq_data * 259static struct regmap_irq_chip s5m8763_irq_chip = {
229irq_to_s5m8763_irq(struct sec_pmic_dev *sec_pmic, int irq)
230{
231 return &s5m8763_irqs[irq - sec_pmic->irq_base];
232}
233
234static void s5m8763_irq_lock(struct irq_data *data)
235{
236 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
237
238 mutex_lock(&sec_pmic->irqlock);
239}
240
241static void s5m8763_irq_sync_unlock(struct irq_data *data)
242{
243 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
244 int i;
245
246 for (i = 0; i < ARRAY_SIZE(sec_pmic->irq_masks_cur); i++) {
247 if (sec_pmic->irq_masks_cur[i] != sec_pmic->irq_masks_cache[i]) {
248 sec_pmic->irq_masks_cache[i] = sec_pmic->irq_masks_cur[i];
249 sec_reg_write(sec_pmic, S5M8763_REG_IRQM1 + i,
250 sec_pmic->irq_masks_cur[i]);
251 }
252 }
253
254 mutex_unlock(&sec_pmic->irqlock);
255}
256
257static void s5m8763_irq_unmask(struct irq_data *data)
258{
259 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
260 struct sec_irq_data *irq_data = irq_to_s5m8763_irq(sec_pmic,
261 data->irq);
262
263 sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
264}
265
266static void s5m8763_irq_mask(struct irq_data *data)
267{
268 struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
269 struct sec_irq_data *irq_data = irq_to_s5m8763_irq(sec_pmic,
270 data->irq);
271
272 sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
273}
274
275static struct irq_chip s5m8763_irq_chip = {
276 .name = "s5m8763", 260 .name = "s5m8763",
277 .irq_bus_lock = s5m8763_irq_lock, 261 .irqs = s5m8763_irqs,
278 .irq_bus_sync_unlock = s5m8763_irq_sync_unlock, 262 .num_irqs = ARRAY_SIZE(s5m8763_irqs),
279 .irq_mask = s5m8763_irq_mask, 263 .num_regs = 4,
280 .irq_unmask = s5m8763_irq_unmask, 264 .status_base = S5M8763_REG_IRQ1,
265 .mask_base = S5M8763_REG_IRQM1,
266 .ack_base = S5M8763_REG_IRQ1,
281}; 267};
282 268
283
284static irqreturn_t s5m8767_irq_thread(int irq, void *data)
285{
286 struct sec_pmic_dev *sec_pmic = data;
287 u8 irq_reg[NUM_IRQ_REGS-1];
288 int ret;
289 int i;
290
291
292 ret = sec_bulk_read(sec_pmic, S5M8767_REG_INT1,
293 NUM_IRQ_REGS - 1, irq_reg);
294 if (ret < 0) {
295 dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n",
296 ret);
297 return IRQ_NONE;
298 }
299
300 for (i = 0; i < NUM_IRQ_REGS - 1; i++)
301 irq_reg[i] &= ~sec_pmic->irq_masks_cur[i];
302
303 for (i = 0; i < S5M8767_IRQ_NR; i++) {
304 if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
305 handle_nested_irq(sec_pmic->irq_base + i);
306 }
307
308 return IRQ_HANDLED;
309}
310
311static irqreturn_t s5m8763_irq_thread(int irq, void *data)
312{
313 struct sec_pmic_dev *sec_pmic = data;
314 u8 irq_reg[NUM_IRQ_REGS];
315 int ret;
316 int i;
317
318 ret = sec_bulk_read(sec_pmic, S5M8763_REG_IRQ1,
319 NUM_IRQ_REGS, irq_reg);
320 if (ret < 0) {
321 dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n",
322 ret);
323 return IRQ_NONE;
324 }
325
326 for (i = 0; i < NUM_IRQ_REGS; i++)
327 irq_reg[i] &= ~sec_pmic->irq_masks_cur[i];
328
329 for (i = 0; i < S5M8763_IRQ_NR; i++) {
330 if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
331 handle_nested_irq(sec_pmic->irq_base + i);
332 }
333
334 return IRQ_HANDLED;
335}
336
337int sec_irq_resume(struct sec_pmic_dev *sec_pmic)
338{
339 if (sec_pmic->irq && sec_pmic->irq_base) {
340 switch (sec_pmic->device_type) {
341 case S5M8763X:
342 s5m8763_irq_thread(sec_pmic->irq_base, sec_pmic);
343 break;
344 case S5M8767X:
345 s5m8767_irq_thread(sec_pmic->irq_base, sec_pmic);
346 break;
347 default:
348 dev_err(sec_pmic->dev,
349 "Unknown device type %d\n",
350 sec_pmic->device_type);
351 return -EINVAL;
352
353 }
354 }
355 return 0;
356}
357
358int sec_irq_init(struct sec_pmic_dev *sec_pmic) 269int sec_irq_init(struct sec_pmic_dev *sec_pmic)
359{ 270{
360 int i;
361 int cur_irq;
362 int ret = 0; 271 int ret = 0;
363 int type = sec_pmic->device_type; 272 int type = sec_pmic->device_type;
364 273
@@ -369,119 +278,33 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
369 return 0; 278 return 0;
370 } 279 }
371 280
372 if (!sec_pmic->irq_base) {
373 dev_err(sec_pmic->dev,
374 "No interrupt base specified, no interrupts\n");
375 return 0;
376 }
377
378 mutex_init(&sec_pmic->irqlock);
379
380 switch (type) { 281 switch (type) {
381 case S5M8763X: 282 case S5M8763X:
382 for (i = 0; i < NUM_IRQ_REGS; i++) { 283 ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
383 sec_pmic->irq_masks_cur[i] = 0xff; 284 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
384 sec_pmic->irq_masks_cache[i] = 0xff; 285 sec_pmic->irq_base, &s5m8763_irq_chip,
385 sec_reg_write(sec_pmic, S5M8763_REG_IRQM1 + i, 286 &sec_pmic->irq_data);
386 0xff);
387 }
388
389 sec_reg_write(sec_pmic, S5M8763_REG_STATUSM1, 0xff);
390 sec_reg_write(sec_pmic, S5M8763_REG_STATUSM2, 0xff);
391
392 for (i = 0; i < S5M8763_IRQ_NR; i++) {
393 cur_irq = i + sec_pmic->irq_base;
394 irq_set_chip_data(cur_irq, sec_pmic);
395 irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
396 handle_edge_irq);
397 irq_set_nested_thread(cur_irq, 1);
398#ifdef CONFIG_ARM
399 set_irq_flags(cur_irq, IRQF_VALID);
400#else
401 irq_set_noprobe(cur_irq);
402#endif
403 }
404
405 ret = request_threaded_irq(sec_pmic->irq, NULL,
406 s5m8763_irq_thread,
407 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
408 "sec-pmic-irq", sec_pmic);
409 if (ret) {
410 dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n",
411 sec_pmic->irq, ret);
412 return ret;
413 }
414 break; 287 break;
415 case S5M8767X: 288 case S5M8767X:
416 for (i = 0; i < NUM_IRQ_REGS - 1; i++) { 289 ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
417 sec_pmic->irq_masks_cur[i] = 0xff; 290 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
418 sec_pmic->irq_masks_cache[i] = 0xff; 291 sec_pmic->irq_base, &s5m8767_irq_chip,
419 sec_reg_write(sec_pmic, S5M8767_REG_INT1M + i, 292 &sec_pmic->irq_data);
420 0xff);
421 }
422 for (i = 0; i < S5M8767_IRQ_NR; i++) {
423 cur_irq = i + sec_pmic->irq_base;
424 irq_set_chip_data(cur_irq, sec_pmic);
425 if (ret) {
426 dev_err(sec_pmic->dev,
427 "Failed to irq_set_chip_data %d: %d\n",
428 sec_pmic->irq, ret);
429 return ret;
430 }
431
432 irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
433 handle_edge_irq);
434 irq_set_nested_thread(cur_irq, 1);
435#ifdef CONFIG_ARM
436 set_irq_flags(cur_irq, IRQF_VALID);
437#else
438 irq_set_noprobe(cur_irq);
439#endif
440 }
441
442 ret = request_threaded_irq(sec_pmic->irq, NULL,
443 s5m8767_irq_thread,
444 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
445 "sec-pmic-irq", sec_pmic);
446 if (ret) {
447 dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n",
448 sec_pmic->irq, ret);
449 return ret;
450 }
451 break; 293 break;
452 default: 294 case S2MPS11X:
453 dev_err(sec_pmic->dev, 295 ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
454 "Unknown device type %d\n", sec_pmic->device_type); 296 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
455 return -EINVAL; 297 sec_pmic->irq_base, &s2mps11_irq_chip,
456 } 298 &sec_pmic->irq_data);
457
458 if (!sec_pmic->ono)
459 return 0;
460
461 switch (type) {
462 case S5M8763X:
463 ret = request_threaded_irq(sec_pmic->ono, NULL,
464 s5m8763_irq_thread,
465 IRQF_TRIGGER_FALLING |
466 IRQF_TRIGGER_RISING |
467 IRQF_ONESHOT, "sec_pmic-ono",
468 sec_pmic);
469 break;
470 case S5M8767X:
471 ret = request_threaded_irq(sec_pmic->ono, NULL,
472 s5m8767_irq_thread,
473 IRQF_TRIGGER_FALLING |
474 IRQF_TRIGGER_RISING |
475 IRQF_ONESHOT, "sec_pmic-ono", sec_pmic);
476 break; 299 break;
477 default: 300 default:
478 ret = -EINVAL; 301 dev_err(sec_pmic->dev, "Unknown device type %d\n",
479 break; 302 sec_pmic->device_type);
303 return -EINVAL;
480 } 304 }
481 305
482 if (ret) { 306 if (ret != 0) {
483 dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", 307 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
484 sec_pmic->ono, ret);
485 return ret; 308 return ret;
486 } 309 }
487 310
@@ -490,9 +313,5 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
490 313
491void sec_irq_exit(struct sec_pmic_dev *sec_pmic) 314void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
492{ 315{
493 if (sec_pmic->ono) 316 regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
494 free_irq(sec_pmic->ono, sec_pmic);
495
496 if (sec_pmic->irq)
497 free_irq(sec_pmic->irq, sec_pmic);
498} 317}