]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/dma/ipu/ipu_irq.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[karo-tx-linux.git] / drivers / dma / ipu / ipu_irq.c
1 /*
2  * Copyright (C) 2008
3  * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9
10 #include <linux/init.h>
11 #include <linux/err.h>
12 #include <linux/spinlock.h>
13 #include <linux/delay.h>
14 #include <linux/clk.h>
15 #include <linux/irq.h>
16 #include <linux/io.h>
17 #include <linux/module.h>
18
19 #include <mach/ipu.h>
20
21 #include "ipu_intern.h"
22
23 /*
24  * Register read / write - shall be inlined by the compiler
25  */
26 static u32 ipu_read_reg(struct ipu *ipu, unsigned long reg)
27 {
28         return __raw_readl(ipu->reg_ipu + reg);
29 }
30
31 static void ipu_write_reg(struct ipu *ipu, u32 value, unsigned long reg)
32 {
33         __raw_writel(value, ipu->reg_ipu + reg);
34 }
35
36
37 /*
38  * IPU IRQ chip driver
39  */
40
41 #define IPU_IRQ_NR_FN_BANKS 3
42 #define IPU_IRQ_NR_ERR_BANKS 2
43 #define IPU_IRQ_NR_BANKS (IPU_IRQ_NR_FN_BANKS + IPU_IRQ_NR_ERR_BANKS)
44
45 struct ipu_irq_bank {
46         unsigned int    control;
47         unsigned int    status;
48         spinlock_t      lock;
49         struct ipu      *ipu;
50 };
51
52 static struct ipu_irq_bank irq_bank[IPU_IRQ_NR_BANKS] = {
53         /* 3 groups of functional interrupts */
54         {
55                 .control        = IPU_INT_CTRL_1,
56                 .status         = IPU_INT_STAT_1,
57         }, {
58                 .control        = IPU_INT_CTRL_2,
59                 .status         = IPU_INT_STAT_2,
60         }, {
61                 .control        = IPU_INT_CTRL_3,
62                 .status         = IPU_INT_STAT_3,
63         },
64         /* 2 groups of error interrupts */
65         {
66                 .control        = IPU_INT_CTRL_4,
67                 .status         = IPU_INT_STAT_4,
68         }, {
69                 .control        = IPU_INT_CTRL_5,
70                 .status         = IPU_INT_STAT_5,
71         },
72 };
73
74 struct ipu_irq_map {
75         unsigned int            irq;
76         int                     source;
77         struct ipu_irq_bank     *bank;
78         struct ipu              *ipu;
79 };
80
81 static struct ipu_irq_map irq_map[CONFIG_MX3_IPU_IRQS];
82 /* Protects allocations from the above array of maps */
83 static DEFINE_MUTEX(map_lock);
84 /* Protects register accesses and individual mappings */
85 static DEFINE_RAW_SPINLOCK(bank_lock);
86
87 static struct ipu_irq_map *src2map(unsigned int src)
88 {
89         int i;
90
91         for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++)
92                 if (irq_map[i].source == src)
93                         return irq_map + i;
94
95         return NULL;
96 }
97
98 static void ipu_irq_unmask(struct irq_data *d)
99 {
100         struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
101         struct ipu_irq_bank *bank;
102         uint32_t reg;
103         unsigned long lock_flags;
104
105         raw_spin_lock_irqsave(&bank_lock, lock_flags);
106
107         bank = map->bank;
108         if (!bank) {
109                 raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
110                 pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
111                 return;
112         }
113
114         reg = ipu_read_reg(bank->ipu, bank->control);
115         reg |= (1UL << (map->source & 31));
116         ipu_write_reg(bank->ipu, reg, bank->control);
117
118         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
119 }
120
121 static void ipu_irq_mask(struct irq_data *d)
122 {
123         struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
124         struct ipu_irq_bank *bank;
125         uint32_t reg;
126         unsigned long lock_flags;
127
128         raw_spin_lock_irqsave(&bank_lock, lock_flags);
129
130         bank = map->bank;
131         if (!bank) {
132                 raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
133                 pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
134                 return;
135         }
136
137         reg = ipu_read_reg(bank->ipu, bank->control);
138         reg &= ~(1UL << (map->source & 31));
139         ipu_write_reg(bank->ipu, reg, bank->control);
140
141         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
142 }
143
144 static void ipu_irq_ack(struct irq_data *d)
145 {
146         struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
147         struct ipu_irq_bank *bank;
148         unsigned long lock_flags;
149
150         raw_spin_lock_irqsave(&bank_lock, lock_flags);
151
152         bank = map->bank;
153         if (!bank) {
154                 raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
155                 pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
156                 return;
157         }
158
159         ipu_write_reg(bank->ipu, 1UL << (map->source & 31), bank->status);
160         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
161 }
162
163 /**
164  * ipu_irq_status() - returns the current interrupt status of the specified IRQ.
165  * @irq:        interrupt line to get status for.
166  * @return:     true if the interrupt is pending/asserted or false if the
167  *              interrupt is not pending.
168  */
169 bool ipu_irq_status(unsigned int irq)
170 {
171         struct ipu_irq_map *map = irq_get_chip_data(irq);
172         struct ipu_irq_bank *bank;
173         unsigned long lock_flags;
174         bool ret;
175
176         raw_spin_lock_irqsave(&bank_lock, lock_flags);
177         bank = map->bank;
178         ret = bank && ipu_read_reg(bank->ipu, bank->status) &
179                 (1UL << (map->source & 31));
180         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
181
182         return ret;
183 }
184
185 /**
186  * ipu_irq_map() - map an IPU interrupt source to an IRQ number
187  * @source:     interrupt source bit position (see below)
188  * @return:     mapped IRQ number or negative error code
189  *
190  * The source parameter has to be explained further. On i.MX31 IPU has 137 IRQ
191  * sources, they are broken down in 5 32-bit registers, like 32, 32, 24, 32, 17.
192  * However, the source argument of this function is not the sequence number of
193  * the possible IRQ, but rather its bit position. So, first interrupt in fourth
194  * register has source number 96, and not 88. This makes calculations easier,
195  * and also provides forward compatibility with any future IPU implementations
196  * with any interrupt bit assignments.
197  */
198 int ipu_irq_map(unsigned int source)
199 {
200         int i, ret = -ENOMEM;
201         struct ipu_irq_map *map;
202
203         might_sleep();
204
205         mutex_lock(&map_lock);
206         map = src2map(source);
207         if (map) {
208                 pr_err("IPU: Source %u already mapped to IRQ %u\n", source, map->irq);
209                 ret = -EBUSY;
210                 goto out;
211         }
212
213         for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
214                 if (irq_map[i].source < 0) {
215                         unsigned long lock_flags;
216
217                         raw_spin_lock_irqsave(&bank_lock, lock_flags);
218                         irq_map[i].source = source;
219                         irq_map[i].bank = irq_bank + source / 32;
220                         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
221
222                         ret = irq_map[i].irq;
223                         pr_debug("IPU: mapped source %u to IRQ %u\n",
224                                  source, ret);
225                         break;
226                 }
227         }
228 out:
229         mutex_unlock(&map_lock);
230
231         if (ret < 0)
232                 pr_err("IPU: couldn't map source %u: %d\n", source, ret);
233
234         return ret;
235 }
236
237 /**
238  * ipu_irq_map() - map an IPU interrupt source to an IRQ number
239  * @source:     interrupt source bit position (see ipu_irq_map())
240  * @return:     0 or negative error code
241  */
242 int ipu_irq_unmap(unsigned int source)
243 {
244         int i, ret = -EINVAL;
245
246         might_sleep();
247
248         mutex_lock(&map_lock);
249         for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
250                 if (irq_map[i].source == source) {
251                         unsigned long lock_flags;
252
253                         pr_debug("IPU: unmapped source %u from IRQ %u\n",
254                                  source, irq_map[i].irq);
255
256                         raw_spin_lock_irqsave(&bank_lock, lock_flags);
257                         irq_map[i].source = -EINVAL;
258                         irq_map[i].bank = NULL;
259                         raw_spin_unlock_irqrestore(&bank_lock, lock_flags);
260
261                         ret = 0;
262                         break;
263                 }
264         }
265         mutex_unlock(&map_lock);
266
267         return ret;
268 }
269
270 /* Chained IRQ handler for IPU error interrupt */
271 static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
272 {
273         struct ipu *ipu = irq_get_handler_data(irq);
274         u32 status;
275         int i, line;
276
277         for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
278                 struct ipu_irq_bank *bank = irq_bank + i;
279
280                 raw_spin_lock(&bank_lock);
281                 status = ipu_read_reg(ipu, bank->status);
282                 /*
283                  * Don't think we have to clear all interrupts here, they will
284                  * be acked by ->handle_irq() (handle_level_irq). However, we
285                  * might want to clear unhandled interrupts after the loop...
286                  */
287                 status &= ipu_read_reg(ipu, bank->control);
288                 raw_spin_unlock(&bank_lock);
289                 while ((line = ffs(status))) {
290                         struct ipu_irq_map *map;
291
292                         line--;
293                         status &= ~(1UL << line);
294
295                         raw_spin_lock(&bank_lock);
296                         map = src2map(32 * i + line);
297                         if (map)
298                                 irq = map->irq;
299                         raw_spin_unlock(&bank_lock);
300
301                         if (!map) {
302                                 pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
303                                        line, i);
304                                 continue;
305                         }
306                         generic_handle_irq(irq);
307                 }
308         }
309 }
310
311 /* Chained IRQ handler for IPU function interrupt */
312 static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
313 {
314         struct ipu *ipu = irq_desc_get_handler_data(desc);
315         u32 status;
316         int i, line;
317
318         for (i = 0; i < IPU_IRQ_NR_FN_BANKS; i++) {
319                 struct ipu_irq_bank *bank = irq_bank + i;
320
321                 raw_spin_lock(&bank_lock);
322                 status = ipu_read_reg(ipu, bank->status);
323                 /* Not clearing all interrupts, see above */
324                 status &= ipu_read_reg(ipu, bank->control);
325                 raw_spin_unlock(&bank_lock);
326                 while ((line = ffs(status))) {
327                         struct ipu_irq_map *map;
328
329                         line--;
330                         status &= ~(1UL << line);
331
332                         raw_spin_lock(&bank_lock);
333                         map = src2map(32 * i + line);
334                         if (map)
335                                 irq = map->irq;
336                         raw_spin_unlock(&bank_lock);
337
338                         if (!map) {
339                                 pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
340                                        line, i);
341                                 continue;
342                         }
343                         generic_handle_irq(irq);
344                 }
345         }
346 }
347
348 static struct irq_chip ipu_irq_chip = {
349         .name           = "ipu_irq",
350         .irq_ack        = ipu_irq_ack,
351         .irq_mask       = ipu_irq_mask,
352         .irq_unmask     = ipu_irq_unmask,
353 };
354
355 /* Install the IRQ handler */
356 int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
357 {
358         unsigned int irq, i;
359         int irq_base = irq_alloc_descs(-1, 0, CONFIG_MX3_IPU_IRQS,
360                                        numa_node_id());
361
362         if (irq_base < 0)
363                 return irq_base;
364
365         for (i = 0; i < IPU_IRQ_NR_BANKS; i++)
366                 irq_bank[i].ipu = ipu;
367
368         for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
369                 int ret;
370
371                 irq = irq_base + i;
372                 ret = irq_set_chip(irq, &ipu_irq_chip);
373                 if (ret < 0)
374                         return ret;
375                 ret = irq_set_chip_data(irq, irq_map + i);
376                 if (ret < 0)
377                         return ret;
378                 irq_map[i].ipu = ipu;
379                 irq_map[i].irq = irq;
380                 irq_map[i].source = -EINVAL;
381                 irq_set_handler(irq, handle_level_irq);
382 #ifdef CONFIG_ARM
383                 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
384 #endif
385         }
386
387         irq_set_handler_data(ipu->irq_fn, ipu);
388         irq_set_chained_handler(ipu->irq_fn, ipu_irq_fn);
389
390         irq_set_handler_data(ipu->irq_err, ipu);
391         irq_set_chained_handler(ipu->irq_err, ipu_irq_err);
392
393         ipu->irq_base = irq_base;
394
395         return 0;
396 }
397
398 void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
399 {
400         unsigned int irq, irq_base;
401
402         irq_base = ipu->irq_base;
403
404         irq_set_chained_handler(ipu->irq_fn, NULL);
405         irq_set_handler_data(ipu->irq_fn, NULL);
406
407         irq_set_chained_handler(ipu->irq_err, NULL);
408         irq_set_handler_data(ipu->irq_err, NULL);
409
410         for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) {
411 #ifdef CONFIG_ARM
412                 set_irq_flags(irq, 0);
413 #endif
414                 irq_set_chip(irq, NULL);
415                 irq_set_chip_data(irq, NULL);
416         }
417 }