diff options
author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-10-10 08:58:29 -0400 |
---|---|---|
committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2008-01-25 02:31:43 -0500 |
commit | e7ba176b47db2ed53f258a6b4fe9d9fc6fa437a9 (patch) | |
tree | beb9ffab7da0c24f11c04b6eb4ca29b23b1dd07b /arch/avr32/mach-at32ap/extint.c | |
parent | f6135d12db4bed3b992052020f1c50d749cd8dc6 (diff) |
[AVR32] NMI debugging
Change the NMI handler to use the die notifier chain to signal anyone
who cares. Add a simple "nmi debugger" which hooks into this chain and
that may dump registers, task state, etc. when it happens.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32/mach-at32ap/extint.c')
-rw-r--r-- | arch/avr32/mach-at32ap/extint.c | 39 |
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 | ||
60 | static struct eic *nmi_eic; | ||
61 | static bool nmi_enabled; | ||
62 | |||
66 | static void eic_ack_irq(unsigned int irq) | 63 | static 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 | ||
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 | |||
177 | static int __init eic_probe(struct platform_device *pdev) | 192 | static 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); |