aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/extint.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap/extint.c')
-rw-r--r--arch/avr32/mach-at32ap/extint.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index f5bfd4c81fe7..e108e7bba8c0 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -26,16 +26,10 @@
26#define EIC_MODE 0x0014 26#define EIC_MODE 0x0014
27#define EIC_EDGE 0x0018 27#define EIC_EDGE 0x0018
28#define EIC_LEVEL 0x001c 28#define EIC_LEVEL 0x001c
29#define EIC_TEST 0x0020
30#define EIC_NMIC 0x0024 29#define EIC_NMIC 0x0024
31 30
32/* Bitfields in TEST */
33#define EIC_TESTEN_OFFSET 31
34#define EIC_TESTEN_SIZE 1
35
36/* Bitfields in NMIC */ 31/* Bitfields in NMIC */
37#define EIC_EN_OFFSET 0 32#define EIC_NMIC_ENABLE (1 << 0)
38#define EIC_EN_SIZE 1
39 33
40/* Bit manipulation macros */ 34/* Bit manipulation macros */
41#define EIC_BIT(name) \ 35#define EIC_BIT(name) \
@@ -63,6 +57,9 @@ struct eic {
63 unsigned int first_irq; 57 unsigned int first_irq;
64}; 58};
65 59
60static struct eic *nmi_eic;
61static bool nmi_enabled;
62
66static void eic_ack_irq(unsigned int irq) 63static void eic_ack_irq(unsigned int irq)
67{ 64{
68 struct eic *eic = get_irq_chip_data(irq); 65 struct eic *eic = get_irq_chip_data(irq);
@@ -174,6 +171,24 @@ static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
174 } 171 }
175} 172}
176 173
174int 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
184void nmi_disable(void)
185{
186 if (nmi_eic)
187 eic_writel(nmi_eic, NMIC, 0);
188
189 nmi_enabled = false;
190}
191
177static int __init eic_probe(struct platform_device *pdev) 192static int __init eic_probe(struct platform_device *pdev)
178{ 193{
179 struct eic *eic; 194 struct eic *eic;
@@ -230,6 +245,16 @@ static int __init eic_probe(struct platform_device *pdev)
230 set_irq_chained_handler(int_irq, demux_eic_irq); 245 set_irq_chained_handler(int_irq, demux_eic_irq);
231 set_irq_data(int_irq, eic); 246 set_irq_data(int_irq, eic);
232 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
233 dev_info(&pdev->dev, 258 dev_info(&pdev->dev,
234 "External Interrupt Controller at 0x%p, IRQ %u\n", 259 "External Interrupt Controller at 0x%p, IRQ %u\n",
235 eic->regs, int_irq); 260 eic->regs, int_irq);