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