diff options
author | Pannaga Bhushan <p.bhushan@samsung.com> | 2010-05-24 02:08:31 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2010-05-26 06:09:50 -0400 |
commit | 5fae405838527c136a920eb7b9a2edfc5d2b6198 (patch) | |
tree | 5d5bdf81c15d383c67632552d0a1f10efd31ee7c /arch/arm | |
parent | b1cdc4670b9508fcd47a15fbd12f70d269880b37 (diff) |
ARM: S5P: Fix the platform external interrupt issues.
This patch does the following:
1. Corrects the common platform code for external interrupts for using the
VIC mask/unmask bits also.
2. Moves the common defines related to external interrupt for plat-s5p
to common files.
3. Based on the new common defines, corresponding changes are made in the
affected platforms (S5P6440, S5P6442 and S5PC100).
Signed-off-by: Pannaga Bhushan <p.bhushan@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-s5p6440/include/mach/irqs.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/include/mach/irqs.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-s5pc100/include/mach/irqs.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/irqs.h | 14 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/regs-gpio.h | 14 | ||||
-rw-r--r-- | arch/arm/plat-s5p/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-s5p/include/plat/irqs.h | 7 | ||||
-rw-r--r-- | arch/arm/plat-s5p/irq-eint.c | 15 |
8 files changed, 40 insertions, 28 deletions
diff --git a/arch/arm/mach-s5p6440/include/mach/irqs.h b/arch/arm/mach-s5p6440/include/mach/irqs.h index a4b9b40d18f2..911854d9ad42 100644 --- a/arch/arm/mach-s5p6440/include/mach/irqs.h +++ b/arch/arm/mach-s5p6440/include/mach/irqs.h | |||
@@ -72,7 +72,14 @@ | |||
72 | #define S5P_IRQ_EINT_BASE (S5P_IRQ_VIC1(31) + 6) | 72 | #define S5P_IRQ_EINT_BASE (S5P_IRQ_VIC1(31) + 6) |
73 | 73 | ||
74 | #define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE) | 74 | #define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE) |
75 | #define IRQ_EINT(x) S5P_EINT(x) | 75 | |
76 | #define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE) | ||
77 | /* | ||
78 | * S5P6440 has 0-15 external interrupts in group 0. Only these can be used | ||
79 | * to wake up from sleep. If request is beyond this range, by mistake, a large | ||
80 | * return value for an irq number should be indication of something amiss. | ||
81 | */ | ||
82 | #define S5P_EINT_BASE2 (0xf0000000) | ||
76 | 83 | ||
77 | /* | 84 | /* |
78 | * Next the external interrupt groups. These are similar to the IRQ_EINT(x) | 85 | * Next the external interrupt groups. These are similar to the IRQ_EINT(x) |
diff --git a/arch/arm/mach-s5p6442/include/mach/irqs.h b/arch/arm/mach-s5p6442/include/mach/irqs.h index da665809f6e4..02c23749c023 100644 --- a/arch/arm/mach-s5p6442/include/mach/irqs.h +++ b/arch/arm/mach-s5p6442/include/mach/irqs.h | |||
@@ -77,8 +77,9 @@ | |||
77 | 77 | ||
78 | #define S5P_IRQ_EINT_BASE (IRQ_VIC_END + 1) | 78 | #define S5P_IRQ_EINT_BASE (IRQ_VIC_END + 1) |
79 | 79 | ||
80 | #define IRQ_EINT(x) ((x) < 16 ? S5P_IRQ_VIC0(x) : \ | 80 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) |
81 | (S5P_IRQ_EINT_BASE + (x)-16)) | 81 | #define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE) |
82 | |||
82 | /* Set the default NR_IRQS */ | 83 | /* Set the default NR_IRQS */ |
83 | 84 | ||
84 | #define NR_IRQS (IRQ_EINT(31) + 1) | 85 | #define NR_IRQS (IRQ_EINT(31) + 1) |
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h index 15066df3ced9..28aa551dc3a8 100644 --- a/arch/arm/mach-s5pc100/include/mach/irqs.h +++ b/arch/arm/mach-s5pc100/include/mach/irqs.h | |||
@@ -100,9 +100,6 @@ | |||
100 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) | 100 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) |
101 | #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) | 101 | #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) |
102 | 102 | ||
103 | #define IRQ_EINT(x) ((x) < 16 ? S5P_IRQ_VIC0(x) : \ | ||
104 | (S5P_EINT_BASE2 + (x) - 16)) | ||
105 | |||
106 | #define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1) | 103 | #define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1) |
107 | #define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x)) | 104 | #define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x)) |
108 | 105 | ||
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h index 92fc6c7fc064..96895378ea27 100644 --- a/arch/arm/mach-s5pv210/include/mach/irqs.h +++ b/arch/arm/mach-s5pv210/include/mach/irqs.h | |||
@@ -118,22 +118,12 @@ | |||
118 | #define IRQ_MDNIE3 S5P_IRQ_VIC3(8) | 118 | #define IRQ_MDNIE3 S5P_IRQ_VIC3(8) |
119 | #define IRQ_VIC_END S5P_IRQ_VIC3(31) | 119 | #define IRQ_VIC_END S5P_IRQ_VIC3(31) |
120 | 120 | ||
121 | #define S5P_EINT_16_31_BASE (IRQ_VIC_END + 1) | 121 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) |
122 | 122 | #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) | |
123 | #define EINT_MODE S3C_GPIO_SFN(0xf) | ||
124 | |||
125 | #define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_IRQ_VIC0(0)) \ | ||
126 | : ((x) + S5P_EINT_16_31_BASE)) | ||
127 | 123 | ||
128 | /* Set the default NR_IRQS */ | 124 | /* Set the default NR_IRQS */ |
129 | |||
130 | #define NR_IRQS (IRQ_EINT(31) + 1) | 125 | #define NR_IRQS (IRQ_EINT(31) + 1) |
131 | 126 | ||
132 | #define EINT_GPIO_0(x) S5PV210_GPH0(x) | ||
133 | #define EINT_GPIO_1(x) S5PV210_GPH1(x) | ||
134 | #define EINT_GPIO_2(x) S5PV210_GPH2(x) | ||
135 | #define EINT_GPIO_3(x) S5PV210_GPH3(x) | ||
136 | |||
137 | /* Compatibility */ | 127 | /* Compatibility */ |
138 | #define IRQ_LCD_FIFO IRQ_LCD0 | 128 | #define IRQ_LCD_FIFO IRQ_LCD0 |
139 | #define IRQ_LCD_VSYNC IRQ_LCD1 | 129 | #define IRQ_LCD_VSYNC IRQ_LCD1 |
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h index 6d068091c36c..49e029b4978a 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h | |||
@@ -27,12 +27,9 @@ | |||
27 | #define S5PV210_EINT30PEND (S5P_VA_GPIO + 0xF40) | 27 | #define S5PV210_EINT30PEND (S5P_VA_GPIO + 0xF40) |
28 | #define S5P_EINT_PEND(x) (S5PV210_EINT30PEND + ((x) * 0x4)) | 28 | #define S5P_EINT_PEND(x) (S5PV210_EINT30PEND + ((x) * 0x4)) |
29 | 29 | ||
30 | #define eint_offset(irq) ((irq) < IRQ_EINT16_31 ? ((irq) - IRQ_EINT(0)) \ | 30 | #define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) |
31 | : ((irq) - S5P_EINT_16_31_BASE)) | ||
32 | 31 | ||
33 | #define EINT_REG_NR(x) (eint_offset(x) >> 3) | 32 | #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) |
34 | |||
35 | #define eint_irq_to_bit(irq) (1 << (eint_offset(irq) & 0x7)) | ||
36 | 33 | ||
37 | /* values for S5P_EXTINT0 */ | 34 | /* values for S5P_EXTINT0 */ |
38 | #define S5P_EXTINT_LOWLEV (0x00) | 35 | #define S5P_EXTINT_LOWLEV (0x00) |
@@ -41,4 +38,11 @@ | |||
41 | #define S5P_EXTINT_RISEEDGE (0x03) | 38 | #define S5P_EXTINT_RISEEDGE (0x03) |
42 | #define S5P_EXTINT_BOTHEDGE (0x04) | 39 | #define S5P_EXTINT_BOTHEDGE (0x04) |
43 | 40 | ||
41 | #define EINT_MODE S3C_GPIO_SFN(0xf) | ||
42 | |||
43 | #define EINT_GPIO_0(x) S5PV210_GPH0(x) | ||
44 | #define EINT_GPIO_1(x) S5PV210_GPH1(x) | ||
45 | #define EINT_GPIO_2(x) S5PV210_GPH2(x) | ||
46 | #define EINT_GPIO_3(x) S5PV210_GPH3(x) | ||
47 | |||
44 | #endif /* __ASM_ARCH_REGS_GPIO_H */ | 48 | #endif /* __ASM_ARCH_REGS_GPIO_H */ |
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 5cb2dd1da632..11d6a1bbd90d 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig | |||
@@ -29,3 +29,4 @@ config S5P_EXT_INT | |||
29 | bool | 29 | bool |
30 | help | 30 | help |
31 | Use the external interrupts (other than GPIO interrupts.) | 31 | Use the external interrupts (other than GPIO interrupts.) |
32 | Note: Do not choose this for S5P6440. | ||
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 9ff3d718be39..3fb3a3a17465 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h | |||
@@ -87,4 +87,11 @@ | |||
87 | #define IRQ_TIMER3 S5P_TIMER_IRQ(3) | 87 | #define IRQ_TIMER3 S5P_TIMER_IRQ(3) |
88 | #define IRQ_TIMER4 S5P_TIMER_IRQ(4) | 88 | #define IRQ_TIMER4 S5P_TIMER_IRQ(4) |
89 | 89 | ||
90 | #define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ | ||
91 | : ((x) - 16 + S5P_EINT_BASE2)) | ||
92 | |||
93 | #define EINT_OFFSET(irq) ((irq) < S5P_EINT_BASE2 ? \ | ||
94 | ((irq) - S5P_EINT_BASE1) : \ | ||
95 | ((irq) + 16 - S5P_EINT_BASE2)) | ||
96 | |||
90 | #endif /* __ASM_PLAT_S5P_IRQS_H */ | 97 | #endif /* __ASM_PLAT_S5P_IRQS_H */ |
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index eaa70aa0127b..e56c8075df97 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c | |||
@@ -60,7 +60,7 @@ static void s5p_irq_eint_maskack(unsigned int irq) | |||
60 | 60 | ||
61 | static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) | 61 | static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) |
62 | { | 62 | { |
63 | int offs = eint_offset(irq); | 63 | int offs = EINT_OFFSET(irq); |
64 | int shift; | 64 | int shift; |
65 | u32 ctrl, mask; | 65 | u32 ctrl, mask; |
66 | u32 newvalue = 0; | 66 | u32 newvalue = 0; |
@@ -139,17 +139,16 @@ static struct irq_chip s5p_irq_eint = { | |||
139 | */ | 139 | */ |
140 | static inline void s5p_irq_demux_eint(unsigned int start) | 140 | static inline void s5p_irq_demux_eint(unsigned int start) |
141 | { | 141 | { |
142 | u32 status; | 142 | u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); |
143 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); | 143 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); |
144 | unsigned int irq; | 144 | unsigned int irq; |
145 | 145 | ||
146 | status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); | ||
147 | status &= ~mask; | 146 | status &= ~mask; |
148 | status &= 0xff; | 147 | status &= 0xff; |
149 | 148 | ||
150 | while (status) { | 149 | while (status) { |
151 | irq = fls(status); | 150 | irq = fls(status) - 1; |
152 | generic_handle_irq(irq - 1 + start); | 151 | generic_handle_irq(irq + start); |
153 | status &= ~(1 << irq); | 152 | status &= ~(1 << irq); |
154 | } | 153 | } |
155 | } | 154 | } |
@@ -162,12 +161,18 @@ static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | |||
162 | 161 | ||
163 | static inline void s5p_irq_vic_eint_mask(unsigned int irq) | 162 | static inline void s5p_irq_vic_eint_mask(unsigned int irq) |
164 | { | 163 | { |
164 | void __iomem *base = get_irq_chip_data(irq); | ||
165 | |||
165 | s5p_irq_eint_mask(irq); | 166 | s5p_irq_eint_mask(irq); |
167 | writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE_CLEAR); | ||
166 | } | 168 | } |
167 | 169 | ||
168 | static void s5p_irq_vic_eint_unmask(unsigned int irq) | 170 | static void s5p_irq_vic_eint_unmask(unsigned int irq) |
169 | { | 171 | { |
172 | void __iomem *base = get_irq_chip_data(irq); | ||
173 | |||
170 | s5p_irq_eint_unmask(irq); | 174 | s5p_irq_eint_unmask(irq); |
175 | writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE); | ||
171 | } | 176 | } |
172 | 177 | ||
173 | static inline void s5p_irq_vic_eint_ack(unsigned int irq) | 178 | static inline void s5p_irq_vic_eint_ack(unsigned int irq) |