aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarius Augulis <augulis.darius@gmail.com>2008-09-09 05:29:41 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2008-09-09 06:13:50 -0400
commit479c901f59762732dee305166ae477171cae3617 (patch)
treeb061499771021b431d54ec46fe66b3b31be4a37f
parentd7568f79d5c289d0d7859680be7b5afdcea0c9b2 (diff)
MXC: Lets handle IRQ by priority, defined with exported API function
Signed-off-by: Darius Augulis <augulis.darius@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/plat-mxc/Kconfig11
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S12
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h1
-rw-r--r--arch/arm/plat-mxc/irq.c35
4 files changed, 48 insertions, 11 deletions
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index e14eaad11dd..b2a7e3fad11 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -23,4 +23,15 @@ source "arch/arm/mach-mx3/Kconfig"
23 23
24endmenu 24endmenu
25 25
26config MXC_IRQ_PRIOR
27 bool "Use IRQ priority"
28 depends on ARCH_MXC
29 help
30 Select this if you want to use prioritized IRQ handling.
31 This feature prevents higher priority ISR to be interrupted
32 by lower priority IRQ even IRQF_DISABLED flag is not set.
33 This may be useful in embedded applications, where are strong
34 requirements for timing.
35 Say N here, unless you have a specialized requirement.
36
26endif 37endif
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index b542433afb1..11632028f7d 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -9,11 +9,17 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#define AVIC_NIMASK 0x04
13
12 @ this macro disables fast irq (not implemented) 14 @ this macro disables fast irq (not implemented)
13 .macro disable_fiq 15 .macro disable_fiq
14 .endm 16 .endm
15 17
16 .macro get_irqnr_preamble, base, tmp 18 .macro get_irqnr_preamble, base, tmp
19 ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
20#ifdef CONFIG_MXC_IRQ_PRIOR
21 ldr r4, [\base, #AVIC_NIMASK]
22#endif
17 .endm 23 .endm
18 24
19 .macro arch_ret_to_user, tmp1, tmp2 25 .macro arch_ret_to_user, tmp1, tmp2
@@ -23,7 +29,6 @@
23 @ and returns its number in irqnr 29 @ and returns its number in irqnr
24 @ and returns if an interrupt occured in irqstat 30 @ and returns if an interrupt occured in irqstat
25 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 31 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
26 ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
27 @ Load offset & priority of the highest priority 32 @ Load offset & priority of the highest priority
28 @ interrupt pending from AVIC_NIVECSR 33 @ interrupt pending from AVIC_NIVECSR
29 ldr \irqstat, [\base, #0x40] 34 ldr \irqstat, [\base, #0x40]
@@ -32,6 +37,11 @@
32 mov \irqnr, \irqstat, asr #16 37 mov \irqnr, \irqstat, asr #16
33 @ set zero flag if IRQ + 1 == 0 38 @ set zero flag if IRQ + 1 == 0
34 adds \tmp, \irqnr, #1 39 adds \tmp, \irqnr, #1
40#ifdef CONFIG_MXC_IRQ_PRIOR
41 bicne \tmp, \irqstat, #0xFFFFFFE0
42 strne \tmp, [\base, #AVIC_NIMASK]
43 streq r4, [\base, #AVIC_NIMASK]
44#endif
35 .endm 45 .endm
36 46
37 @ irq priority table (not used) 47 @ irq priority table (not used)
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 228c4f68ccd..b55bba35e18 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -12,5 +12,6 @@
12#define __ASM_ARCH_MXC_IRQS_H__ 12#define __ASM_ARCH_MXC_IRQS_H__
13 13
14#include <mach/hardware.h> 14#include <mach/hardware.h>
15extern void imx_irq_set_priority(unsigned char irq, unsigned char prio);
15 16
16#endif /* __ASM_ARCH_MXC_IRQS_H__ */ 17#endif /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 1053b666c67..a41abf0bdd6 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -30,14 +30,7 @@
30#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ 30#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */
31#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ 31#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */
32#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ 32#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */
33#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ 33#define AVIC_NIPRIORITY(x) (AVIC_BASE + (0x20 + 4 * (7 - (x)))) /* int priority */
34#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */
35#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */
36#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */
37#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */
38#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */
39#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */
40#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */
41#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ 34#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */
42#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ 35#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */
43#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ 36#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */
@@ -54,6 +47,24 @@
54#define IIM_PROD_REV_SH 3 47#define IIM_PROD_REV_SH 3
55#define IIM_PROD_REV_LEN 5 48#define IIM_PROD_REV_LEN 5
56 49
50#ifdef CONFIG_MXC_IRQ_PRIOR
51void imx_irq_set_priority(unsigned char irq, unsigned char prio)
52{
53 unsigned int temp;
54 unsigned int mask = 0x0F << irq % 8 * 4;
55
56 if (irq > 63)
57 return;
58
59 temp = __raw_readl(AVIC_NIPRIORITY(irq / 8));
60 temp &= ~mask;
61 temp |= prio & mask;
62
63 __raw_writel(temp, AVIC_NIPRIORITY(irq / 8));
64}
65EXPORT_SYMBOL(imx_irq_set_priority);
66#endif
67
57/* Disable interrupt number "irq" in the AVIC */ 68/* Disable interrupt number "irq" in the AVIC */
58static void mxc_mask_irq(unsigned int irq) 69static void mxc_mask_irq(unsigned int irq)
59{ 70{
@@ -101,10 +112,14 @@ void __init mxc_init_irq(void)
101 set_irq_flags(i, IRQF_VALID); 112 set_irq_flags(i, IRQF_VALID);
102 } 113 }
103 114
115 /* Set default priority value (0) for all IRQ's */
116 for (i = 0; i < 8; i++)
117 __raw_writel(0, AVIC_NIPRIORITY(i));
118
104 /* Set WDOG2's interrupt the highest priority level (bit 28-31) */ 119 /* Set WDOG2's interrupt the highest priority level (bit 28-31) */
105 reg = __raw_readl(AVIC_NIPRIORITY6); 120 reg = __raw_readl(AVIC_NIPRIORITY(6));
106 reg |= (0xF << 28); 121 reg |= (0xF << 28);
107 __raw_writel(reg, AVIC_NIPRIORITY6); 122 __raw_writel(reg, AVIC_NIPRIORITY(6));
108 123
109 /* init architectures chained interrupt handler */ 124 /* init architectures chained interrupt handler */
110 mxc_register_gpios(); 125 mxc_register_gpios();