e9d12058ffd379287bd4044e522a6a6736dd727c
[linux-2.6.git] / arch / avr32 / mach-at32ap / extint.c
1 /*
2  * External interrupt handling for AT32AP CPUs
3  *
4  * Copyright (C) 2006 Atmel Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/errno.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/irq.h>
15 #include <linux/platform_device.h>
16 #include <linux/random.h>
17 #include <linux/slab.h>
18
19 #include <asm/io.h>
20
21 /* EIC register offsets */
22 #define EIC_IER                                 0x0000
23 #define EIC_IDR                                 0x0004
24 #define EIC_IMR                                 0x0008
25 #define EIC_ISR                                 0x000c
26 #define EIC_ICR                                 0x0010
27 #define EIC_MODE                                0x0014
28 #define EIC_EDGE                                0x0018
29 #define EIC_LEVEL                               0x001c
30 #define EIC_NMIC                                0x0024
31
32 /* Bitfields in NMIC */
33 #define EIC_NMIC_ENABLE                         (1 << 0)
34
35 /* Bit manipulation macros */
36 #define EIC_BIT(name)                                   \
37         (1 << EIC_##name##_OFFSET)
38 #define EIC_BF(name,value)                              \
39         (((value) & ((1 << EIC_##name##_SIZE) - 1))     \
40          << EIC_##name##_OFFSET)
41 #define EIC_BFEXT(name,value)                           \
42         (((value) >> EIC_##name##_OFFSET)               \
43          & ((1 << EIC_##name##_SIZE) - 1))
44 #define EIC_BFINS(name,value,old)                       \
45         (((old) & ~(((1 << EIC_##name##_SIZE) - 1)      \
46                     << EIC_##name##_OFFSET))            \
47          | EIC_BF(name,value))
48
49 /* Register access macros */
50 #define eic_readl(port,reg)                             \
51         __raw_readl((port)->regs + EIC_##reg)
52 #define eic_writel(port,reg,value)                      \
53         __raw_writel((value), (port)->regs + EIC_##reg)
54
55 struct eic {
56         void __iomem *regs;
57         struct irq_chip *chip;
58         unsigned int first_irq;
59 };
60
61 static struct eic *nmi_eic;
62 static bool nmi_enabled;
63
64 static void eic_ack_irq(unsigned int irq)
65 {
66         struct eic *eic = get_irq_chip_data(irq);
67         eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
68 }
69
70 static void eic_mask_irq(unsigned int irq)
71 {
72         struct eic *eic = get_irq_chip_data(irq);
73         eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
74 }
75
76 static void eic_mask_ack_irq(unsigned int irq)
77 {
78         struct eic *eic = get_irq_chip_data(irq);
79         eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
80         eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
81 }
82
83 static void eic_unmask_irq(unsigned int irq)
84 {
85         struct eic *eic = get_irq_chip_data(irq);
86         eic_writel(eic, IER, 1 << (irq - eic->first_irq));
87 }
88
89 static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
90 {
91         struct eic *eic = get_irq_chip_data(irq);
92         struct irq_desc *desc;
93         unsigned int i = irq - eic->first_irq;
94         u32 mode, edge, level;
95         int ret = 0;
96
97         flow_type &= IRQ_TYPE_SENSE_MASK;
98         if (flow_type == IRQ_TYPE_NONE)
99                 flow_type = IRQ_TYPE_LEVEL_LOW;
100
101         desc = &irq_desc[irq];
102
103         mode = eic_readl(eic, MODE);
104         edge = eic_readl(eic, EDGE);
105         level = eic_readl(eic, LEVEL);
106
107         switch (flow_type) {
108         case IRQ_TYPE_LEVEL_LOW:
109                 mode |= 1 << i;
110                 level &= ~(1 << i);
111                 break;
112         case IRQ_TYPE_LEVEL_HIGH:
113                 mode |= 1 << i;
114                 level |= 1 << i;
115                 break;
116         case IRQ_TYPE_EDGE_RISING:
117                 mode &= ~(1 << i);
118                 edge |= 1 << i;
119                 break;
120         case IRQ_TYPE_EDGE_FALLING:
121                 mode &= ~(1 << i);
122                 edge &= ~(1 << i);
123                 break;
124         default:
125                 ret = -EINVAL;
126                 break;
127         }
128
129         if (ret == 0) {
130                 eic_writel(eic, MODE, mode);
131                 eic_writel(eic, EDGE, edge);
132                 eic_writel(eic, LEVEL, level);
133
134                 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
135                         flow_type |= IRQ_LEVEL;
136                         __set_irq_handler_unlocked(irq, handle_level_irq);
137                 } else
138                         __set_irq_handler_unlocked(irq, handle_edge_irq);
139                 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
140                 desc->status |= flow_type;
141         }
142
143         return ret;
144 }
145
146 static struct irq_chip eic_chip = {
147         .name           = "eic",
148         .ack            = eic_ack_irq,
149         .mask           = eic_mask_irq,
150         .mask_ack       = eic_mask_ack_irq,
151         .unmask         = eic_unmask_irq,
152         .set_type       = eic_set_irq_type,
153 };
154
155 static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
156 {
157         struct eic *eic = desc->handler_data;
158         unsigned long status, pending;
159         unsigned int i;
160
161         status = eic_readl(eic, ISR);
162         pending = status & eic_readl(eic, IMR);
163
164         while (pending) {
165                 i = fls(pending) - 1;
166                 pending &= ~(1 << i);
167
168                 generic_handle_irq(i + eic->first_irq);
169         }
170 }
171
172 int nmi_enable(void)
173 {
174         nmi_enabled = true;
175
176         if (nmi_eic)
177                 eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE);
178
179         return 0;
180 }
181
182 void nmi_disable(void)
183 {
184         if (nmi_eic)
185                 eic_writel(nmi_eic, NMIC, 0);
186
187         nmi_enabled = false;
188 }
189
190 static int __init eic_probe(struct platform_device *pdev)
191 {
192         struct eic *eic;
193         struct resource *regs;
194         unsigned int i;
195         unsigned int nr_of_irqs;
196         unsigned int int_irq;
197         int ret;
198         u32 pattern;
199
200         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
201         int_irq = platform_get_irq(pdev, 0);
202         if (!regs || !int_irq) {
203                 dev_dbg(&pdev->dev, "missing regs and/or irq resource\n");
204                 return -ENXIO;
205         }
206
207         ret = -ENOMEM;
208         eic = kzalloc(sizeof(struct eic), GFP_KERNEL);
209         if (!eic) {
210                 dev_dbg(&pdev->dev, "no memory for eic structure\n");
211                 goto err_kzalloc;
212         }
213
214         eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id;
215         eic->regs = ioremap(regs->start, regs->end - regs->start + 1);
216         if (!eic->regs) {
217                 dev_dbg(&pdev->dev, "failed to map regs\n");
218                 goto err_ioremap;
219         }
220
221         /*
222          * Find out how many interrupt lines that are actually
223          * implemented in hardware.
224          */
225         eic_writel(eic, IDR, ~0UL);
226         eic_writel(eic, MODE, ~0UL);
227         pattern = eic_readl(eic, MODE);
228         nr_of_irqs = fls(pattern);
229
230         /* Trigger on low level unless overridden by driver */
231         eic_writel(eic, EDGE, 0UL);
232         eic_writel(eic, LEVEL, 0UL);
233
234         eic->chip = &eic_chip;
235
236         for (i = 0; i < nr_of_irqs; i++) {
237                 set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
238                                          handle_level_irq);
239                 set_irq_chip_data(eic->first_irq + i, eic);
240         }
241
242         set_irq_chained_handler(int_irq, demux_eic_irq);
243         set_irq_data(int_irq, eic);
244
245         if (pdev->id == 0) {
246                 nmi_eic = eic;
247                 if (nmi_enabled)
248                         /*
249                          * Someone tried to enable NMI before we were
250                          * ready. Do it now.
251                          */
252                         nmi_enable();
253         }
254
255         dev_info(&pdev->dev,
256                  "External Interrupt Controller at 0x%p, IRQ %u\n",
257                  eic->regs, int_irq);
258         dev_info(&pdev->dev,
259                  "Handling %u external IRQs, starting with IRQ %u\n",
260                  nr_of_irqs, eic->first_irq);
261
262         return 0;
263
264 err_ioremap:
265         kfree(eic);
266 err_kzalloc:
267         return ret;
268 }
269
270 static struct platform_driver eic_driver = {
271         .driver = {
272                 .name = "at32_eic",
273         },
274 };
275
276 static int __init eic_init(void)
277 {
278         return platform_driver_probe(&eic_driver, eic_probe);
279 }
280 arch_initcall(eic_init);