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