2 * External interrupt handling for AT32AP CPUs
4 * Copyright (C) 2006 Atmel Corporation
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.
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>
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
32 /* Bitfields in TEST */
33 #define EIC_TESTEN_OFFSET 31
34 #define EIC_TESTEN_SIZE 1
36 /* Bitfields in NMIC */
37 #define EIC_EN_OFFSET 0
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)) \
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)
62 struct irq_chip
*chip
;
63 unsigned int first_irq
;
66 static void eic_ack_irq(unsigned int irq
)
68 struct eic
*eic
= get_irq_chip_data(irq
);
69 eic_writel(eic
, ICR
, 1 << (irq
- eic
->first_irq
));
72 static void eic_mask_irq(unsigned int irq
)
74 struct eic
*eic
= get_irq_chip_data(irq
);
75 eic_writel(eic
, IDR
, 1 << (irq
- eic
->first_irq
));
78 static void eic_mask_ack_irq(unsigned int irq
)
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
));
85 static void eic_unmask_irq(unsigned int irq
)
87 struct eic
*eic
= get_irq_chip_data(irq
);
88 eic_writel(eic
, IER
, 1 << (irq
- eic
->first_irq
));
91 static int eic_set_irq_type(unsigned int irq
, unsigned int flow_type
)
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
;
99 flow_type
&= IRQ_TYPE_SENSE_MASK
;
100 if (flow_type
== IRQ_TYPE_NONE
)
101 flow_type
= IRQ_TYPE_LEVEL_LOW
;
103 desc
= &irq_desc
[irq
];
105 mode
= eic_readl(eic
, MODE
);
106 edge
= eic_readl(eic
, EDGE
);
107 level
= eic_readl(eic
, LEVEL
);
110 case IRQ_TYPE_LEVEL_LOW
:
114 case IRQ_TYPE_LEVEL_HIGH
:
118 case IRQ_TYPE_EDGE_RISING
:
122 case IRQ_TYPE_EDGE_FALLING
:
132 eic_writel(eic
, MODE
, mode
);
133 eic_writel(eic
, EDGE
, edge
);
134 eic_writel(eic
, LEVEL
, level
);
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
;
145 struct irq_chip eic_chip
= {
148 .mask
= eic_mask_irq
,
149 .mask_ack
= eic_mask_ack_irq
,
150 .unmask
= eic_unmask_irq
,
151 .set_type
= eic_set_irq_type
,
154 static void demux_eic_irq(unsigned int irq
, struct irq_desc
*desc
)
156 struct eic
*eic
= desc
->handler_data
;
157 struct irq_desc
*ext_desc
;
158 unsigned long status
, pending
;
159 unsigned int i
, ext_irq
;
161 status
= eic_readl(eic
, ISR
);
162 pending
= status
& eic_readl(eic
, IMR
);
165 i
= fls(pending
) - 1;
166 pending
&= ~(1 << i
);
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
);
173 handle_edge_irq(ext_irq
, ext_desc
);
177 static int __init
eic_probe(struct platform_device
*pdev
)
180 struct resource
*regs
;
182 unsigned int nr_irqs
;
183 unsigned int int_irq
;
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");
195 eic
= kzalloc(sizeof(struct eic
), GFP_KERNEL
);
197 dev_dbg(&pdev
->dev
, "no memory for eic structure\n");
201 eic
->first_irq
= EIM_IRQ_BASE
+ 32 * pdev
->id
;
202 eic
->regs
= ioremap(regs
->start
, regs
->end
- regs
->start
+ 1);
204 dev_dbg(&pdev
->dev
, "failed to map regs\n");
209 * Find out how many interrupt lines that are actually
210 * implemented in hardware.
212 eic_writel(eic
, IDR
, ~0UL);
213 eic_writel(eic
, MODE
, ~0UL);
214 pattern
= eic_readl(eic
, MODE
);
215 nr_irqs
= fls(pattern
);
217 /* Trigger on falling edge unless overridden by driver */
218 eic_writel(eic
, MODE
, 0UL);
219 eic_writel(eic
, EDGE
, 0UL);
221 eic
->chip
= &eic_chip
;
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
,
227 set_irq_chip_data(eic
->first_irq
+ i
, eic
);
230 set_irq_chained_handler(int_irq
, demux_eic_irq
);
231 set_irq_data(int_irq
, eic
);
234 "External Interrupt Controller at 0x%p, IRQ %u\n",
237 "Handling %u external IRQs, starting with IRQ %u\n",
238 nr_irqs
, eic
->first_irq
);
248 static struct platform_driver eic_driver
= {
254 static int __init
eic_init(void)
256 return platform_driver_probe(&eic_driver
, eic_probe
);
258 arch_initcall(eic_init
);