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>
17 #include <linux/slab.h>
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
32 /* Bitfields in NMIC */
33 #define EIC_NMIC_ENABLE (1 << 0)
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)) \
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)
57 struct irq_chip
*chip
;
58 unsigned int first_irq
;
61 static struct eic
*nmi_eic
;
62 static bool nmi_enabled
;
64 static void eic_ack_irq(struct irq_data
*d
)
66 struct eic
*eic
= irq_data_get_irq_chip_data(d
);
67 eic_writel(eic
, ICR
, 1 << (d
->irq
- eic
->first_irq
));
70 static void eic_mask_irq(struct irq_data
*d
)
72 struct eic
*eic
= irq_data_get_irq_chip_data(d
);
73 eic_writel(eic
, IDR
, 1 << (d
->irq
- eic
->first_irq
));
76 static void eic_mask_ack_irq(struct irq_data
*d
)
78 struct eic
*eic
= irq_data_get_irq_chip_data(d
);
79 eic_writel(eic
, ICR
, 1 << (d
->irq
- eic
->first_irq
));
80 eic_writel(eic
, IDR
, 1 << (d
->irq
- eic
->first_irq
));
83 static void eic_unmask_irq(struct irq_data
*d
)
85 struct eic
*eic
= irq_data_get_irq_chip_data(d
);
86 eic_writel(eic
, IER
, 1 << (d
->irq
- eic
->first_irq
));
89 static int eic_set_irq_type(struct irq_data
*d
, unsigned int flow_type
)
91 struct eic
*eic
= irq_data_get_irq_chip_data(d
);
92 unsigned int irq
= d
->irq
;
93 unsigned int i
= irq
- eic
->first_irq
;
94 u32 mode
, edge
, level
;
96 flow_type
&= IRQ_TYPE_SENSE_MASK
;
97 if (flow_type
== IRQ_TYPE_NONE
)
98 flow_type
= IRQ_TYPE_LEVEL_LOW
;
100 mode
= eic_readl(eic
, MODE
);
101 edge
= eic_readl(eic
, EDGE
);
102 level
= eic_readl(eic
, LEVEL
);
105 case IRQ_TYPE_LEVEL_LOW
:
109 case IRQ_TYPE_LEVEL_HIGH
:
113 case IRQ_TYPE_EDGE_RISING
:
117 case IRQ_TYPE_EDGE_FALLING
:
125 eic_writel(eic
, MODE
, mode
);
126 eic_writel(eic
, EDGE
, edge
);
127 eic_writel(eic
, LEVEL
, level
);
129 irqd_set_trigger_type(d
, flow_type
);
130 if (flow_type
& (IRQ_TYPE_LEVEL_LOW
| IRQ_TYPE_LEVEL_HIGH
))
131 __irq_set_handler_locked(irq
, handle_level_irq
);
133 __irq_set_handler_locked(irq
, handle_edge_irq
);
135 return IRQ_SET_MASK_OK_NOCOPY
;
138 static struct irq_chip eic_chip
= {
140 .irq_ack
= eic_ack_irq
,
141 .irq_mask
= eic_mask_irq
,
142 .irq_mask_ack
= eic_mask_ack_irq
,
143 .irq_unmask
= eic_unmask_irq
,
144 .irq_set_type
= eic_set_irq_type
,
147 static void demux_eic_irq(unsigned int irq
, struct irq_desc
*desc
)
149 struct eic
*eic
= irq_desc_get_handler_data(desc
);
150 unsigned long status
, pending
;
153 status
= eic_readl(eic
, ISR
);
154 pending
= status
& eic_readl(eic
, IMR
);
157 i
= fls(pending
) - 1;
158 pending
&= ~(1 << i
);
160 generic_handle_irq(i
+ eic
->first_irq
);
169 eic_writel(nmi_eic
, NMIC
, EIC_NMIC_ENABLE
);
174 void nmi_disable(void)
177 eic_writel(nmi_eic
, NMIC
, 0);
182 static int __init
eic_probe(struct platform_device
*pdev
)
185 struct resource
*regs
;
187 unsigned int nr_of_irqs
;
188 unsigned int int_irq
;
192 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
193 int_irq
= platform_get_irq(pdev
, 0);
194 if (!regs
|| (int)int_irq
<= 0) {
195 dev_dbg(&pdev
->dev
, "missing regs and/or irq resource\n");
200 eic
= kzalloc(sizeof(struct eic
), GFP_KERNEL
);
202 dev_dbg(&pdev
->dev
, "no memory for eic structure\n");
206 eic
->first_irq
= EIM_IRQ_BASE
+ 32 * pdev
->id
;
207 eic
->regs
= ioremap(regs
->start
, resource_size(regs
));
209 dev_dbg(&pdev
->dev
, "failed to map regs\n");
214 * Find out how many interrupt lines that are actually
215 * implemented in hardware.
217 eic_writel(eic
, IDR
, ~0UL);
218 eic_writel(eic
, MODE
, ~0UL);
219 pattern
= eic_readl(eic
, MODE
);
220 nr_of_irqs
= fls(pattern
);
222 /* Trigger on low level unless overridden by driver */
223 eic_writel(eic
, EDGE
, 0UL);
224 eic_writel(eic
, LEVEL
, 0UL);
226 eic
->chip
= &eic_chip
;
228 for (i
= 0; i
< nr_of_irqs
; i
++) {
229 irq_set_chip_and_handler(eic
->first_irq
+ i
, &eic_chip
,
231 irq_set_chip_data(eic
->first_irq
+ i
, eic
);
234 irq_set_chained_handler(int_irq
, demux_eic_irq
);
235 irq_set_handler_data(int_irq
, eic
);
241 * Someone tried to enable NMI before we were
248 "External Interrupt Controller at 0x%p, IRQ %u\n",
251 "Handling %u external IRQs, starting with IRQ %u\n",
252 nr_of_irqs
, eic
->first_irq
);
262 static struct platform_driver eic_driver
= {
268 static int __init
eic_init(void)
270 return platform_driver_probe(&eic_driver
, eic_probe
);
272 arch_initcall(eic_init
);