Commit | Line | Data |
---|---|---|
5ac2ffa7 | 1 | /* |
63063bfb | 2 | * sec-irq.c |
5ac2ffa7 SK |
3 | * |
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | |
5 | * http://www.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> | |
54227bcf SK |
17 | #include <linux/mfd/samsung/core.h> |
18 | #include <linux/mfd/samsung/irq.h> | |
19 | #include <linux/mfd/samsung/s5m8763.h> | |
20 | #include <linux/mfd/samsung/s5m8767.h> | |
5ac2ffa7 | 21 | |
63063bfb | 22 | struct sec_irq_data { |
5ac2ffa7 SK |
23 | int reg; |
24 | int mask; | |
25 | }; | |
26 | ||
63063bfb | 27 | static struct sec_irq_data s5m8767_irqs[] = { |
5ac2ffa7 SK |
28 | [S5M8767_IRQ_PWRR] = { |
29 | .reg = 1, | |
30 | .mask = S5M8767_IRQ_PWRR_MASK, | |
31 | }, | |
32 | [S5M8767_IRQ_PWRF] = { | |
33 | .reg = 1, | |
34 | .mask = S5M8767_IRQ_PWRF_MASK, | |
35 | }, | |
36 | [S5M8767_IRQ_PWR1S] = { | |
37 | .reg = 1, | |
38 | .mask = S5M8767_IRQ_PWR1S_MASK, | |
39 | }, | |
40 | [S5M8767_IRQ_JIGR] = { | |
41 | .reg = 1, | |
42 | .mask = S5M8767_IRQ_JIGR_MASK, | |
43 | }, | |
44 | [S5M8767_IRQ_JIGF] = { | |
45 | .reg = 1, | |
46 | .mask = S5M8767_IRQ_JIGF_MASK, | |
47 | }, | |
48 | [S5M8767_IRQ_LOWBAT2] = { | |
49 | .reg = 1, | |
50 | .mask = S5M8767_IRQ_LOWBAT2_MASK, | |
51 | }, | |
52 | [S5M8767_IRQ_LOWBAT1] = { | |
53 | .reg = 1, | |
54 | .mask = S5M8767_IRQ_LOWBAT1_MASK, | |
55 | }, | |
56 | [S5M8767_IRQ_MRB] = { | |
57 | .reg = 2, | |
58 | .mask = S5M8767_IRQ_MRB_MASK, | |
59 | }, | |
60 | [S5M8767_IRQ_DVSOK2] = { | |
61 | .reg = 2, | |
62 | .mask = S5M8767_IRQ_DVSOK2_MASK, | |
63 | }, | |
64 | [S5M8767_IRQ_DVSOK3] = { | |
65 | .reg = 2, | |
66 | .mask = S5M8767_IRQ_DVSOK3_MASK, | |
67 | }, | |
68 | [S5M8767_IRQ_DVSOK4] = { | |
69 | .reg = 2, | |
70 | .mask = S5M8767_IRQ_DVSOK4_MASK, | |
71 | }, | |
72 | [S5M8767_IRQ_RTC60S] = { | |
73 | .reg = 3, | |
74 | .mask = S5M8767_IRQ_RTC60S_MASK, | |
75 | }, | |
76 | [S5M8767_IRQ_RTCA1] = { | |
77 | .reg = 3, | |
78 | .mask = S5M8767_IRQ_RTCA1_MASK, | |
79 | }, | |
80 | [S5M8767_IRQ_RTCA2] = { | |
81 | .reg = 3, | |
82 | .mask = S5M8767_IRQ_RTCA2_MASK, | |
83 | }, | |
84 | [S5M8767_IRQ_SMPL] = { | |
85 | .reg = 3, | |
86 | .mask = S5M8767_IRQ_SMPL_MASK, | |
87 | }, | |
88 | [S5M8767_IRQ_RTC1S] = { | |
89 | .reg = 3, | |
90 | .mask = S5M8767_IRQ_RTC1S_MASK, | |
91 | }, | |
92 | [S5M8767_IRQ_WTSR] = { | |
93 | .reg = 3, | |
94 | .mask = S5M8767_IRQ_WTSR_MASK, | |
95 | }, | |
96 | }; | |
97 | ||
63063bfb | 98 | static struct sec_irq_data s5m8763_irqs[] = { |
5ac2ffa7 SK |
99 | [S5M8763_IRQ_DCINF] = { |
100 | .reg = 1, | |
101 | .mask = S5M8763_IRQ_DCINF_MASK, | |
102 | }, | |
103 | [S5M8763_IRQ_DCINR] = { | |
104 | .reg = 1, | |
105 | .mask = S5M8763_IRQ_DCINR_MASK, | |
106 | }, | |
107 | [S5M8763_IRQ_JIGF] = { | |
108 | .reg = 1, | |
109 | .mask = S5M8763_IRQ_JIGF_MASK, | |
110 | }, | |
111 | [S5M8763_IRQ_JIGR] = { | |
112 | .reg = 1, | |
113 | .mask = S5M8763_IRQ_JIGR_MASK, | |
114 | }, | |
115 | [S5M8763_IRQ_PWRONF] = { | |
116 | .reg = 1, | |
117 | .mask = S5M8763_IRQ_PWRONF_MASK, | |
118 | }, | |
119 | [S5M8763_IRQ_PWRONR] = { | |
120 | .reg = 1, | |
121 | .mask = S5M8763_IRQ_PWRONR_MASK, | |
122 | }, | |
123 | [S5M8763_IRQ_WTSREVNT] = { | |
124 | .reg = 2, | |
125 | .mask = S5M8763_IRQ_WTSREVNT_MASK, | |
126 | }, | |
127 | [S5M8763_IRQ_SMPLEVNT] = { | |
128 | .reg = 2, | |
129 | .mask = S5M8763_IRQ_SMPLEVNT_MASK, | |
130 | }, | |
131 | [S5M8763_IRQ_ALARM1] = { | |
132 | .reg = 2, | |
133 | .mask = S5M8763_IRQ_ALARM1_MASK, | |
134 | }, | |
135 | [S5M8763_IRQ_ALARM0] = { | |
136 | .reg = 2, | |
137 | .mask = S5M8763_IRQ_ALARM0_MASK, | |
138 | }, | |
139 | [S5M8763_IRQ_ONKEY1S] = { | |
140 | .reg = 3, | |
141 | .mask = S5M8763_IRQ_ONKEY1S_MASK, | |
142 | }, | |
143 | [S5M8763_IRQ_TOPOFFR] = { | |
144 | .reg = 3, | |
145 | .mask = S5M8763_IRQ_TOPOFFR_MASK, | |
146 | }, | |
147 | [S5M8763_IRQ_DCINOVPR] = { | |
148 | .reg = 3, | |
149 | .mask = S5M8763_IRQ_DCINOVPR_MASK, | |
150 | }, | |
151 | [S5M8763_IRQ_CHGRSTF] = { | |
152 | .reg = 3, | |
153 | .mask = S5M8763_IRQ_CHGRSTF_MASK, | |
154 | }, | |
155 | [S5M8763_IRQ_DONER] = { | |
156 | .reg = 3, | |
157 | .mask = S5M8763_IRQ_DONER_MASK, | |
158 | }, | |
159 | [S5M8763_IRQ_CHGFAULT] = { | |
160 | .reg = 3, | |
161 | .mask = S5M8763_IRQ_CHGFAULT_MASK, | |
162 | }, | |
163 | [S5M8763_IRQ_LOBAT1] = { | |
164 | .reg = 4, | |
165 | .mask = S5M8763_IRQ_LOBAT1_MASK, | |
166 | }, | |
167 | [S5M8763_IRQ_LOBAT2] = { | |
168 | .reg = 4, | |
169 | .mask = S5M8763_IRQ_LOBAT2_MASK, | |
170 | }, | |
171 | }; | |
172 | ||
63063bfb SK |
173 | static inline struct sec_irq_data * |
174 | irq_to_s5m8767_irq(struct sec_pmic_dev *sec_pmic, int irq) | |
5ac2ffa7 | 175 | { |
63063bfb | 176 | return &s5m8767_irqs[irq - sec_pmic->irq_base]; |
5ac2ffa7 SK |
177 | } |
178 | ||
179 | static void s5m8767_irq_lock(struct irq_data *data) | |
180 | { | |
63063bfb | 181 | struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); |
5ac2ffa7 | 182 | |
63063bfb | 183 | mutex_lock(&sec_pmic->irqlock); |
5ac2ffa7 SK |
184 | } |
185 | ||
186 | static void s5m8767_irq_sync_unlock(struct irq_data *data) | |
187 | { | |
63063bfb | 188 | struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); |
5ac2ffa7 SK |
189 | int i; |
190 | ||
63063bfb SK |
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]); | |
5ac2ffa7 SK |
196 | } |
197 | } | |
198 | ||
63063bfb | 199 | mutex_unlock(&sec_pmic->irqlock); |
5ac2ffa7 SK |
200 | } |
201 | ||
202 | static void s5m8767_irq_unmask(struct irq_data *data) | |
203 | { | |
63063bfb SK |
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, | |
5ac2ffa7 SK |
206 | data->irq); |
207 | ||
63063bfb | 208 | sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
5ac2ffa7 SK |
209 | } |
210 | ||
211 | static void s5m8767_irq_mask(struct irq_data *data) | |
212 | { | |
63063bfb SK |
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, | |
5ac2ffa7 SK |
215 | data->irq); |
216 | ||
63063bfb | 217 | sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
5ac2ffa7 SK |
218 | } |
219 | ||
220 | static struct irq_chip s5m8767_irq_chip = { | |
221 | .name = "s5m8767", | |
222 | .irq_bus_lock = s5m8767_irq_lock, | |
223 | .irq_bus_sync_unlock = s5m8767_irq_sync_unlock, | |
224 | .irq_mask = s5m8767_irq_mask, | |
225 | .irq_unmask = s5m8767_irq_unmask, | |
226 | }; | |
227 | ||
63063bfb SK |
228 | static inline struct sec_irq_data * |
229 | irq_to_s5m8763_irq(struct sec_pmic_dev *sec_pmic, int irq) | |
5ac2ffa7 | 230 | { |
63063bfb | 231 | return &s5m8763_irqs[irq - sec_pmic->irq_base]; |
5ac2ffa7 SK |
232 | } |
233 | ||
234 | static void s5m8763_irq_lock(struct irq_data *data) | |
235 | { | |
63063bfb | 236 | struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); |
5ac2ffa7 | 237 | |
63063bfb | 238 | mutex_lock(&sec_pmic->irqlock); |
5ac2ffa7 SK |
239 | } |
240 | ||
241 | static void s5m8763_irq_sync_unlock(struct irq_data *data) | |
242 | { | |
63063bfb | 243 | struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); |
5ac2ffa7 SK |
244 | int i; |
245 | ||
63063bfb SK |
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]); | |
5ac2ffa7 SK |
251 | } |
252 | } | |
253 | ||
63063bfb | 254 | mutex_unlock(&sec_pmic->irqlock); |
5ac2ffa7 SK |
255 | } |
256 | ||
257 | static void s5m8763_irq_unmask(struct irq_data *data) | |
258 | { | |
63063bfb SK |
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, | |
5ac2ffa7 SK |
261 | data->irq); |
262 | ||
63063bfb | 263 | sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
5ac2ffa7 SK |
264 | } |
265 | ||
266 | static void s5m8763_irq_mask(struct irq_data *data) | |
267 | { | |
63063bfb SK |
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, | |
5ac2ffa7 SK |
270 | data->irq); |
271 | ||
63063bfb | 272 | sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
5ac2ffa7 SK |
273 | } |
274 | ||
275 | static struct irq_chip s5m8763_irq_chip = { | |
276 | .name = "s5m8763", | |
277 | .irq_bus_lock = s5m8763_irq_lock, | |
278 | .irq_bus_sync_unlock = s5m8763_irq_sync_unlock, | |
279 | .irq_mask = s5m8763_irq_mask, | |
280 | .irq_unmask = s5m8763_irq_unmask, | |
281 | }; | |
282 | ||
283 | ||
284 | static irqreturn_t s5m8767_irq_thread(int irq, void *data) | |
285 | { | |
63063bfb | 286 | struct sec_pmic_dev *sec_pmic = data; |
5ac2ffa7 SK |
287 | u8 irq_reg[NUM_IRQ_REGS-1]; |
288 | int ret; | |
289 | int i; | |
290 | ||
291 | ||
63063bfb | 292 | ret = sec_bulk_read(sec_pmic, S5M8767_REG_INT1, |
5ac2ffa7 SK |
293 | NUM_IRQ_REGS - 1, irq_reg); |
294 | if (ret < 0) { | |
63063bfb | 295 | dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n", |
5ac2ffa7 SK |
296 | ret); |
297 | return IRQ_NONE; | |
298 | } | |
299 | ||
300 | for (i = 0; i < NUM_IRQ_REGS - 1; i++) | |
63063bfb | 301 | irq_reg[i] &= ~sec_pmic->irq_masks_cur[i]; |
5ac2ffa7 SK |
302 | |
303 | for (i = 0; i < S5M8767_IRQ_NR; i++) { | |
304 | if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask) | |
63063bfb | 305 | handle_nested_irq(sec_pmic->irq_base + i); |
5ac2ffa7 SK |
306 | } |
307 | ||
308 | return IRQ_HANDLED; | |
309 | } | |
310 | ||
311 | static irqreturn_t s5m8763_irq_thread(int irq, void *data) | |
312 | { | |
63063bfb | 313 | struct sec_pmic_dev *sec_pmic = data; |
5ac2ffa7 SK |
314 | u8 irq_reg[NUM_IRQ_REGS]; |
315 | int ret; | |
316 | int i; | |
317 | ||
63063bfb | 318 | ret = sec_bulk_read(sec_pmic, S5M8763_REG_IRQ1, |
5ac2ffa7 SK |
319 | NUM_IRQ_REGS, irq_reg); |
320 | if (ret < 0) { | |
63063bfb | 321 | dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n", |
5ac2ffa7 SK |
322 | ret); |
323 | return IRQ_NONE; | |
324 | } | |
325 | ||
326 | for (i = 0; i < NUM_IRQ_REGS; i++) | |
63063bfb | 327 | irq_reg[i] &= ~sec_pmic->irq_masks_cur[i]; |
5ac2ffa7 SK |
328 | |
329 | for (i = 0; i < S5M8763_IRQ_NR; i++) { | |
330 | if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask) | |
63063bfb | 331 | handle_nested_irq(sec_pmic->irq_base + i); |
5ac2ffa7 SK |
332 | } |
333 | ||
334 | return IRQ_HANDLED; | |
335 | } | |
336 | ||
63063bfb | 337 | int sec_irq_resume(struct sec_pmic_dev *sec_pmic) |
5ac2ffa7 | 338 | { |
63063bfb SK |
339 | if (sec_pmic->irq && sec_pmic->irq_base) { |
340 | switch (sec_pmic->device_type) { | |
5ac2ffa7 | 341 | case S5M8763X: |
63063bfb | 342 | s5m8763_irq_thread(sec_pmic->irq_base, sec_pmic); |
5ac2ffa7 SK |
343 | break; |
344 | case S5M8767X: | |
63063bfb | 345 | s5m8767_irq_thread(sec_pmic->irq_base, sec_pmic); |
5ac2ffa7 SK |
346 | break; |
347 | default: | |
63063bfb | 348 | dev_err(sec_pmic->dev, |
c7a1fcf3 | 349 | "Unknown device type %d\n", |
63063bfb | 350 | sec_pmic->device_type); |
c7a1fcf3 | 351 | return -EINVAL; |
5ac2ffa7 SK |
352 | |
353 | } | |
354 | } | |
355 | return 0; | |
356 | } | |
357 | ||
63063bfb | 358 | int sec_irq_init(struct sec_pmic_dev *sec_pmic) |
5ac2ffa7 SK |
359 | { |
360 | int i; | |
361 | int cur_irq; | |
362 | int ret = 0; | |
63063bfb | 363 | int type = sec_pmic->device_type; |
5ac2ffa7 | 364 | |
63063bfb SK |
365 | if (!sec_pmic->irq) { |
366 | dev_warn(sec_pmic->dev, | |
5ac2ffa7 | 367 | "No interrupt specified, no interrupts\n"); |
63063bfb | 368 | sec_pmic->irq_base = 0; |
5ac2ffa7 SK |
369 | return 0; |
370 | } | |
371 | ||
63063bfb SK |
372 | if (!sec_pmic->irq_base) { |
373 | dev_err(sec_pmic->dev, | |
5ac2ffa7 SK |
374 | "No interrupt base specified, no interrupts\n"); |
375 | return 0; | |
376 | } | |
377 | ||
63063bfb | 378 | mutex_init(&sec_pmic->irqlock); |
5ac2ffa7 SK |
379 | |
380 | switch (type) { | |
381 | case S5M8763X: | |
382 | for (i = 0; i < NUM_IRQ_REGS; i++) { | |
63063bfb SK |
383 | sec_pmic->irq_masks_cur[i] = 0xff; |
384 | sec_pmic->irq_masks_cache[i] = 0xff; | |
385 | sec_reg_write(sec_pmic, S5M8763_REG_IRQM1 + i, | |
5ac2ffa7 SK |
386 | 0xff); |
387 | } | |
388 | ||
63063bfb SK |
389 | sec_reg_write(sec_pmic, S5M8763_REG_STATUSM1, 0xff); |
390 | sec_reg_write(sec_pmic, S5M8763_REG_STATUSM2, 0xff); | |
5ac2ffa7 SK |
391 | |
392 | for (i = 0; i < S5M8763_IRQ_NR; i++) { | |
63063bfb SK |
393 | cur_irq = i + sec_pmic->irq_base; |
394 | irq_set_chip_data(cur_irq, sec_pmic); | |
5ac2ffa7 SK |
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 | ||
63063bfb | 405 | ret = request_threaded_irq(sec_pmic->irq, NULL, |
5ac2ffa7 SK |
406 | s5m8763_irq_thread, |
407 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | |
63063bfb | 408 | "sec-pmic-irq", sec_pmic); |
5ac2ffa7 | 409 | if (ret) { |
63063bfb SK |
410 | dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", |
411 | sec_pmic->irq, ret); | |
5ac2ffa7 SK |
412 | return ret; |
413 | } | |
414 | break; | |
415 | case S5M8767X: | |
416 | for (i = 0; i < NUM_IRQ_REGS - 1; i++) { | |
63063bfb SK |
417 | sec_pmic->irq_masks_cur[i] = 0xff; |
418 | sec_pmic->irq_masks_cache[i] = 0xff; | |
419 | sec_reg_write(sec_pmic, S5M8767_REG_INT1M + i, | |
5ac2ffa7 SK |
420 | 0xff); |
421 | } | |
422 | for (i = 0; i < S5M8767_IRQ_NR; i++) { | |
63063bfb SK |
423 | cur_irq = i + sec_pmic->irq_base; |
424 | irq_set_chip_data(cur_irq, sec_pmic); | |
5ac2ffa7 | 425 | if (ret) { |
63063bfb | 426 | dev_err(sec_pmic->dev, |
5ac2ffa7 | 427 | "Failed to irq_set_chip_data %d: %d\n", |
63063bfb | 428 | sec_pmic->irq, ret); |
5ac2ffa7 SK |
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 | ||
63063bfb | 442 | ret = request_threaded_irq(sec_pmic->irq, NULL, |
5ac2ffa7 SK |
443 | s5m8767_irq_thread, |
444 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | |
63063bfb | 445 | "sec-pmic-irq", sec_pmic); |
5ac2ffa7 | 446 | if (ret) { |
63063bfb SK |
447 | dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", |
448 | sec_pmic->irq, ret); | |
5ac2ffa7 SK |
449 | return ret; |
450 | } | |
451 | break; | |
452 | default: | |
63063bfb SK |
453 | dev_err(sec_pmic->dev, |
454 | "Unknown device type %d\n", sec_pmic->device_type); | |
c7a1fcf3 | 455 | return -EINVAL; |
5ac2ffa7 SK |
456 | } |
457 | ||
63063bfb | 458 | if (!sec_pmic->ono) |
5ac2ffa7 SK |
459 | return 0; |
460 | ||
461 | switch (type) { | |
462 | case S5M8763X: | |
63063bfb | 463 | ret = request_threaded_irq(sec_pmic->ono, NULL, |
5ac2ffa7 SK |
464 | s5m8763_irq_thread, |
465 | IRQF_TRIGGER_FALLING | | |
466 | IRQF_TRIGGER_RISING | | |
63063bfb SK |
467 | IRQF_ONESHOT, "sec_pmic-ono", |
468 | sec_pmic); | |
5ac2ffa7 SK |
469 | break; |
470 | case S5M8767X: | |
63063bfb | 471 | ret = request_threaded_irq(sec_pmic->ono, NULL, |
5ac2ffa7 SK |
472 | s5m8767_irq_thread, |
473 | IRQF_TRIGGER_FALLING | | |
474 | IRQF_TRIGGER_RISING | | |
63063bfb | 475 | IRQF_ONESHOT, "sec_pmic-ono", sec_pmic); |
5ac2ffa7 SK |
476 | break; |
477 | default: | |
c7a1fcf3 | 478 | ret = -EINVAL; |
5ac2ffa7 SK |
479 | break; |
480 | } | |
481 | ||
c7a1fcf3 | 482 | if (ret) { |
63063bfb SK |
483 | dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", |
484 | sec_pmic->ono, ret); | |
c7a1fcf3 JC |
485 | return ret; |
486 | } | |
5ac2ffa7 SK |
487 | |
488 | return 0; | |
489 | } | |
490 | ||
63063bfb | 491 | void sec_irq_exit(struct sec_pmic_dev *sec_pmic) |
5ac2ffa7 | 492 | { |
63063bfb SK |
493 | if (sec_pmic->ono) |
494 | free_irq(sec_pmic->ono, sec_pmic); | |
5ac2ffa7 | 495 | |
63063bfb SK |
496 | if (sec_pmic->irq) |
497 | free_irq(sec_pmic->irq, sec_pmic); | |
5ac2ffa7 | 498 | } |