Merge git://git.infradead.org/iommu-2.6
[platform/adaptation/renesas_rcar/renesas_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(struct irq_data *data)
106 {
107         struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data);
108
109         mutex_lock(&max8998->irqlock);
110 }
111
112 static void max8998_irq_sync_unlock(struct irq_data *data)
113 {
114         struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data);
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(struct irq_data *data)
133 {
134         struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data);
135         struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998,
136                                                                data->irq);
137
138         max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
139 }
140
141 static void max8998_irq_mask(struct irq_data *data)
142 {
143         struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data);
144         struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998,
145                                                                data->irq);
146
147         max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
148 }
149
150 static struct irq_chip max8998_irq_chip = {
151         .name = "max8998",
152         .irq_bus_lock = max8998_irq_lock,
153         .irq_bus_sync_unlock = max8998_irq_sync_unlock,
154         .irq_mask = max8998_irq_mask,
155         .irq_unmask = max8998_irq_unmask,
156 };
157
158 static irqreturn_t max8998_irq_thread(int irq, void *data)
159 {
160         struct max8998_dev *max8998 = data;
161         u8 irq_reg[MAX8998_NUM_IRQ_REGS];
162         int ret;
163         int i;
164
165         ret = max8998_bulk_read(max8998->i2c, MAX8998_REG_IRQ1,
166                         MAX8998_NUM_IRQ_REGS, irq_reg);
167         if (ret < 0) {
168                 dev_err(max8998->dev, "Failed to read interrupt register: %d\n",
169                                 ret);
170                 return IRQ_NONE;
171         }
172
173         /* Apply masking */
174         for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++)
175                 irq_reg[i] &= ~max8998->irq_masks_cur[i];
176
177         /* Report */
178         for (i = 0; i < MAX8998_IRQ_NR; i++) {
179                 if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask)
180                         handle_nested_irq(max8998->irq_base + i);
181         }
182
183         return IRQ_HANDLED;
184 }
185
186 int max8998_irq_resume(struct max8998_dev *max8998)
187 {
188         if (max8998->irq && max8998->irq_base)
189                 max8998_irq_thread(max8998->irq_base, max8998);
190         return 0;
191 }
192
193 int max8998_irq_init(struct max8998_dev *max8998)
194 {
195         int i;
196         int cur_irq;
197         int ret;
198
199         if (!max8998->irq) {
200                 dev_warn(max8998->dev,
201                          "No interrupt specified, no interrupts\n");
202                 max8998->irq_base = 0;
203                 return 0;
204         }
205
206         if (!max8998->irq_base) {
207                 dev_err(max8998->dev,
208                         "No interrupt base specified, no interrupts\n");
209                 return 0;
210         }
211
212         mutex_init(&max8998->irqlock);
213
214         /* Mask the individual interrupt sources */
215         for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) {
216                 max8998->irq_masks_cur[i] = 0xff;
217                 max8998->irq_masks_cache[i] = 0xff;
218                 max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 0xff);
219         }
220
221         max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff);
222         max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff);
223
224         /* register with genirq */
225         for (i = 0; i < MAX8998_IRQ_NR; i++) {
226                 cur_irq = i + max8998->irq_base;
227                 irq_set_chip_data(cur_irq, max8998);
228                 irq_set_chip_and_handler(cur_irq, &max8998_irq_chip,
229                                          handle_edge_irq);
230                 irq_set_nested_thread(cur_irq, 1);
231 #ifdef CONFIG_ARM
232                 set_irq_flags(cur_irq, IRQF_VALID);
233 #else
234                 irq_set_noprobe(cur_irq);
235 #endif
236         }
237
238         ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread,
239                                    IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
240                                    "max8998-irq", max8998);
241         if (ret) {
242                 dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
243                         max8998->irq, ret);
244                 return ret;
245         }
246
247         if (!max8998->ono)
248                 return 0;
249
250         ret = request_threaded_irq(max8998->ono, NULL, max8998_irq_thread,
251                                    IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
252                                    IRQF_ONESHOT, "max8998-ono", max8998);
253         if (ret)
254                 dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
255                         max8998->ono, ret);
256
257         return 0;
258 }
259
260 void max8998_irq_exit(struct max8998_dev *max8998)
261 {
262         if (max8998->ono)
263                 free_irq(max8998->ono, max8998);
264
265         if (max8998->irq)
266                 free_irq(max8998->irq, max8998);
267 }