hwmon: (applesmc) Ignore some temperature registers
[pandora-kernel.git] / drivers / base / regmap / regmap-irq.c
1 /*
2  * regmap based irq_chip
3  *
4  * Copyright 2011 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/export.h>
14 #include <linux/device.h>
15 #include <linux/regmap.h>
16 #include <linux/irq.h>
17 #include <linux/interrupt.h>
18 #include <linux/irqdomain.h>
19 #include <linux/slab.h>
20
21 #include "internal.h"
22
23 struct regmap_irq_chip_data {
24         struct mutex lock;
25
26         struct regmap *map;
27         struct regmap_irq_chip *chip;
28
29         int irq_base;
30         struct irq_domain *domain;
31
32         unsigned int *status_buf;
33         unsigned int *mask_buf;
34         unsigned int *mask_buf_def;
35
36         unsigned int irq_reg_stride;
37 };
38
39 static inline const
40 struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data,
41                                      int irq)
42 {
43         return &data->chip->irqs[irq];
44 }
45
46 static void regmap_irq_lock(struct irq_data *data)
47 {
48         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
49
50         mutex_lock(&d->lock);
51 }
52
53 static void regmap_irq_sync_unlock(struct irq_data *data)
54 {
55         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
56         struct regmap *map = d->map;
57         int i, ret;
58
59         /*
60          * If there's been a change in the mask write it back to the
61          * hardware.  We rely on the use of the regmap core cache to
62          * suppress pointless writes.
63          */
64         for (i = 0; i < d->chip->num_regs; i++) {
65                 ret = regmap_update_bits(d->map, d->chip->mask_base +
66                                                 (i * map->reg_stride *
67                                                 d->irq_reg_stride),
68                                          d->mask_buf_def[i], d->mask_buf[i]);
69                 if (ret != 0)
70                         dev_err(d->map->dev, "Failed to sync masks in %x\n",
71                                 d->chip->mask_base + (i * map->reg_stride));
72         }
73
74         mutex_unlock(&d->lock);
75 }
76
77 static void regmap_irq_enable(struct irq_data *data)
78 {
79         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
80         struct regmap *map = d->map;
81         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
82
83         d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask;
84 }
85
86 static void regmap_irq_disable(struct irq_data *data)
87 {
88         struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
89         struct regmap *map = d->map;
90         const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
91
92         d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask;
93 }
94
95 static struct irq_chip regmap_irq_chip = {
96         .name                   = "regmap",
97         .irq_bus_lock           = regmap_irq_lock,
98         .irq_bus_sync_unlock    = regmap_irq_sync_unlock,
99         .irq_disable            = regmap_irq_disable,
100         .irq_enable             = regmap_irq_enable,
101 };
102
103 static irqreturn_t regmap_irq_thread(int irq, void *d)
104 {
105         struct regmap_irq_chip_data *data = d;
106         struct regmap_irq_chip *chip = data->chip;
107         struct regmap *map = data->map;
108         int ret, i;
109         bool handled = false;
110
111         /*
112          * Ignore masked IRQs and ack if we need to; we ack early so
113          * there is no race between handling and acknowleding the
114          * interrupt.  We assume that typically few of the interrupts
115          * will fire simultaneously so don't worry about overhead from
116          * doing a write per register.
117          */
118         for (i = 0; i < data->chip->num_regs; i++) {
119                 ret = regmap_read(map, chip->status_base + (i * map->reg_stride
120                                    * data->irq_reg_stride),
121                                    &data->status_buf[i]);
122
123                 if (ret != 0) {
124                         dev_err(map->dev, "Failed to read IRQ status: %d\n",
125                                         ret);
126                         return IRQ_NONE;
127                 }
128
129                 data->status_buf[i] &= ~data->mask_buf[i];
130
131                 if (data->status_buf[i] && chip->ack_base) {
132                         ret = regmap_write(map, chip->ack_base +
133                                                 (i * map->reg_stride *
134                                                 data->irq_reg_stride),
135                                            data->status_buf[i]);
136                         if (ret != 0)
137                                 dev_err(map->dev, "Failed to ack 0x%x: %d\n",
138                                         chip->ack_base + (i * map->reg_stride),
139                                         ret);
140                 }
141         }
142
143         for (i = 0; i < chip->num_irqs; i++) {
144                 if (data->status_buf[chip->irqs[i].reg_offset /
145                                      map->reg_stride] & chip->irqs[i].mask) {
146                         handle_nested_irq(irq_find_mapping(data->domain, i));
147                         handled = true;
148                 }
149         }
150
151         if (handled)
152                 return IRQ_HANDLED;
153         else
154                 return IRQ_NONE;
155 }
156
157 static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
158                           irq_hw_number_t hw)
159 {
160         struct regmap_irq_chip_data *data = h->host_data;
161
162         irq_set_chip_data(virq, data);
163         irq_set_chip_and_handler(virq, &regmap_irq_chip, handle_edge_irq);
164         irq_set_nested_thread(virq, 1);
165
166         /* ARM needs us to explicitly flag the IRQ as valid
167          * and will set them noprobe when we do so. */
168 #ifdef CONFIG_ARM
169         set_irq_flags(virq, IRQF_VALID);
170 #else
171         irq_set_noprobe(virq);
172 #endif
173
174         return 0;
175 }
176
177 static struct irq_domain_ops regmap_domain_ops = {
178         .map    = regmap_irq_map,
179         .xlate  = irq_domain_xlate_twocell,
180 };
181
182 /**
183  * regmap_add_irq_chip(): Use standard regmap IRQ controller handling
184  *
185  * map:       The regmap for the device.
186  * irq:       The IRQ the device uses to signal interrupts
187  * irq_flags: The IRQF_ flags to use for the primary interrupt.
188  * chip:      Configuration for the interrupt controller.
189  * data:      Runtime data structure for the controller, allocated on success
190  *
191  * Returns 0 on success or an errno on failure.
192  *
193  * In order for this to be efficient the chip really should use a
194  * register cache.  The chip driver is responsible for restoring the
195  * register values used by the IRQ controller over suspend and resume.
196  */
197 int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
198                         int irq_base, struct regmap_irq_chip *chip,
199                         struct regmap_irq_chip_data **data)
200 {
201         struct regmap_irq_chip_data *d;
202         int i;
203         int ret = -ENOMEM;
204
205         for (i = 0; i < chip->num_irqs; i++) {
206                 if (chip->irqs[i].reg_offset % map->reg_stride)
207                         return -EINVAL;
208                 if (chip->irqs[i].reg_offset / map->reg_stride >=
209                     chip->num_regs)
210                         return -EINVAL;
211         }
212
213         if (irq_base) {
214                 irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0);
215                 if (irq_base < 0) {
216                         dev_warn(map->dev, "Failed to allocate IRQs: %d\n",
217                                  irq_base);
218                         return irq_base;
219                 }
220         }
221
222         d = kzalloc(sizeof(*d), GFP_KERNEL);
223         if (!d)
224                 return -ENOMEM;
225
226         *data = d;
227
228         d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs,
229                                 GFP_KERNEL);
230         if (!d->status_buf)
231                 goto err_alloc;
232
233         d->mask_buf = kzalloc(sizeof(unsigned int) * chip->num_regs,
234                               GFP_KERNEL);
235         if (!d->mask_buf)
236                 goto err_alloc;
237
238         d->mask_buf_def = kzalloc(sizeof(unsigned int) * chip->num_regs,
239                                   GFP_KERNEL);
240         if (!d->mask_buf_def)
241                 goto err_alloc;
242
243         d->map = map;
244         d->chip = chip;
245         d->irq_base = irq_base;
246
247         if (chip->irq_reg_stride)
248                 d->irq_reg_stride = chip->irq_reg_stride;
249         else
250                 d->irq_reg_stride = 1;
251
252         mutex_init(&d->lock);
253
254         for (i = 0; i < chip->num_irqs; i++)
255                 d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride]
256                         |= chip->irqs[i].mask;
257
258         /* Mask all the interrupts by default */
259         for (i = 0; i < chip->num_regs; i++) {
260                 d->mask_buf[i] = d->mask_buf_def[i];
261                 ret = regmap_write(map, chip->mask_base + (i * map->reg_stride
262                                    * d->irq_reg_stride),
263                                    d->mask_buf[i]);
264                 if (ret != 0) {
265                         dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
266                                 chip->mask_base + (i * map->reg_stride), ret);
267                         goto err_alloc;
268                 }
269         }
270
271         if (irq_base)
272                 d->domain = irq_domain_add_legacy(map->dev->of_node,
273                                                   chip->num_irqs, irq_base, 0,
274                                                   &regmap_domain_ops, d);
275         else
276                 d->domain = irq_domain_add_linear(map->dev->of_node,
277                                                   chip->num_irqs,
278                                                   &regmap_domain_ops, d);
279         if (!d->domain) {
280                 dev_err(map->dev, "Failed to create IRQ domain\n");
281                 ret = -ENOMEM;
282                 goto err_alloc;
283         }
284
285         ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags,
286                                    chip->name, d);
287         if (ret != 0) {
288                 dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret);
289                 goto err_domain;
290         }
291
292         return 0;
293
294 err_domain:
295         /* Should really dispose of the domain but... */
296 err_alloc:
297         kfree(d->mask_buf_def);
298         kfree(d->mask_buf);
299         kfree(d->status_buf);
300         kfree(d);
301         return ret;
302 }
303 EXPORT_SYMBOL_GPL(regmap_add_irq_chip);
304
305 /**
306  * regmap_del_irq_chip(): Stop interrupt handling for a regmap IRQ chip
307  *
308  * @irq: Primary IRQ for the device
309  * @d:   regmap_irq_chip_data allocated by regmap_add_irq_chip()
310  */
311 void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
312 {
313         if (!d)
314                 return;
315
316         free_irq(irq, d);
317         /* We should unmap the domain but... */
318         kfree(d->mask_buf_def);
319         kfree(d->mask_buf);
320         kfree(d->status_buf);
321         kfree(d);
322 }
323 EXPORT_SYMBOL_GPL(regmap_del_irq_chip);
324
325 /**
326  * regmap_irq_chip_get_base(): Retrieve interrupt base for a regmap IRQ chip
327  *
328  * Useful for drivers to request their own IRQs.
329  *
330  * @data: regmap_irq controller to operate on.
331  */
332 int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data)
333 {
334         WARN_ON(!data->irq_base);
335         return data->irq_base;
336 }
337 EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base);
338
339 /**
340  * regmap_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
341  *
342  * Useful for drivers to request their own IRQs.
343  *
344  * @data: regmap_irq controller to operate on.
345  * @irq: index of the interrupt requested in the chip IRQs
346  */
347 int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq)
348 {
349         return irq_create_mapping(data->domain, irq);
350 }
351 EXPORT_SYMBOL_GPL(regmap_irq_get_virq);