aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c24xx/irq-s3c2443.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:03:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:03:32 -0400
commitd61b7a572b292e2be409e13b4b3adf475f18fb29 (patch)
treee9d30390860147136c05e66abf1edda1bc5b0562 /arch/arm/mach-s3c24xx/irq-s3c2443.c
parent18d9946bc7e2252fe3c0f2f609ac383c627edefd (diff)
parentf4e2467bad53023589cbff18dd1ab6e0aa3f004c (diff)
Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull "ARM: global cleanups" from Arnd Bergmann: "Quite a bit of code gets removed, and some stuff moved around, mostly the old samsung s3c24xx stuff. There should be no functional changes in this series otherwise. Some cleanups have dependencies on other arm-soc branches and will be sent in the second round. Signed-off-by: Arnd Bergmann <arnd@arndb.de>" Fixed up trivial conflicts mainly due to #include's being changes on both sides. * tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (121 commits) ep93xx: Remove unnecessary includes of ep93xx-regs.h ep93xx: Move EP93XX_SYSCON defines to SoC private header ep93xx: Move crunch code to mach-ep93xx directory ep93xx: Make syscon access functions private to SoC ep93xx: Configure GPIO ports in core code ep93xx: Move peripheral defines to local SoC header ep93xx: Convert the watchdog driver into a platform device. ep93xx: Use ioremap for backlight driver ep93xx: Move GPIO defines to gpio-ep93xx.h ep93xx: Don't use system controller defines in audio drivers ep93xx: Move PHYS_BASE defines to local SoC header file ARM: EXYNOS: Add clock register addresses for EXYNOS4X12 bus devfreq driver ARM: EXYNOS: add clock registers for exynos4x12-cpufreq PM / devfreq: update the name of EXYNOS clock registers that were omitted PM / devfreq: update the name of EXYNOS clock register ARM: EXYNOS: change the prefix S5P_ to EXYNOS4_ for clock ARM: EXYNOS: use static declaration on regarding clock ARM: EXYNOS: replace clock.c for other new EXYNOS SoCs ARM: OMAP2+: Fix build error after merge ARM: S3C24XX: remove call to s3c24xx_setup_clocks ...
Diffstat (limited to 'arch/arm/mach-s3c24xx/irq-s3c2443.c')
-rw-r--r--arch/arm/mach-s3c24xx/irq-s3c2443.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c
new file mode 100644
index 000000000000..ac2829f56d12
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/irq-s3c2443.c
@@ -0,0 +1,281 @@
1/* linux/arch/arm/mach-s3c2443/irq.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20*/
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/ioport.h>
26#include <linux/device.h>
27#include <linux/io.h>
28
29#include <mach/hardware.h>
30#include <asm/irq.h>
31
32#include <asm/mach/irq.h>
33
34#include <mach/regs-irq.h>
35#include <mach/regs-gpio.h>
36
37#include <plat/cpu.h>
38#include <plat/pm.h>
39#include <plat/irq.h>
40
41#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
42
43static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
44{
45 unsigned int subsrc, submsk;
46 unsigned int end;
47
48 /* read the current pending interrupts, and the mask
49 * for what it is available */
50
51 subsrc = __raw_readl(S3C2410_SUBSRCPND);
52 submsk = __raw_readl(S3C2410_INTSUBMSK);
53
54 subsrc &= ~submsk;
55 subsrc >>= (irq - S3C2410_IRQSUB(0));
56 subsrc &= (1 << len)-1;
57
58 end = len + irq;
59
60 for (; irq < end && subsrc; irq++) {
61 if (subsrc & 1)
62 generic_handle_irq(irq);
63
64 subsrc >>= 1;
65 }
66}
67
68/* WDT/AC97 sub interrupts */
69
70static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
71{
72 s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
73}
74
75#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
76#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
77
78static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
79{
80 s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
81}
82
83static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
84{
85 s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
86}
87
88static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
89{
90 s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
91}
92
93static struct irq_chip s3c2443_irq_wdtac97 = {
94 .irq_mask = s3c2443_irq_wdtac97_mask,
95 .irq_unmask = s3c2443_irq_wdtac97_unmask,
96 .irq_ack = s3c2443_irq_wdtac97_ack,
97};
98
99/* LCD sub interrupts */
100
101static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
102{
103 s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
104}
105
106#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
107#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
108
109static void s3c2443_irq_lcd_mask(struct irq_data *data)
110{
111 s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
112}
113
114static void s3c2443_irq_lcd_unmask(struct irq_data *data)
115{
116 s3c_irqsub_unmask(data->irq, INTMSK_LCD);
117}
118
119static void s3c2443_irq_lcd_ack(struct irq_data *data)
120{
121 s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
122}
123
124static struct irq_chip s3c2443_irq_lcd = {
125 .irq_mask = s3c2443_irq_lcd_mask,
126 .irq_unmask = s3c2443_irq_lcd_unmask,
127 .irq_ack = s3c2443_irq_lcd_ack,
128};
129
130/* DMA sub interrupts */
131
132static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
133{
134 s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
135}
136
137#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
138#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
139
140static void s3c2443_irq_dma_mask(struct irq_data *data)
141{
142 s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
143}
144
145static void s3c2443_irq_dma_unmask(struct irq_data *data)
146{
147 s3c_irqsub_unmask(data->irq, INTMSK_DMA);
148}
149
150static void s3c2443_irq_dma_ack(struct irq_data *data)
151{
152 s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
153}
154
155static struct irq_chip s3c2443_irq_dma = {
156 .irq_mask = s3c2443_irq_dma_mask,
157 .irq_unmask = s3c2443_irq_dma_unmask,
158 .irq_ack = s3c2443_irq_dma_ack,
159};
160
161/* UART3 sub interrupts */
162
163static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
164{
165 s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
166}
167
168#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
169#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
170
171static void s3c2443_irq_uart3_mask(struct irq_data *data)
172{
173 s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
174}
175
176static void s3c2443_irq_uart3_unmask(struct irq_data *data)
177{
178 s3c_irqsub_unmask(data->irq, INTMSK_UART3);
179}
180
181static void s3c2443_irq_uart3_ack(struct irq_data *data)
182{
183 s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
184}
185
186static struct irq_chip s3c2443_irq_uart3 = {
187 .irq_mask = s3c2443_irq_uart3_mask,
188 .irq_unmask = s3c2443_irq_uart3_unmask,
189 .irq_ack = s3c2443_irq_uart3_ack,
190};
191
192/* CAM sub interrupts */
193
194static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
195{
196 s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
197}
198
199#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
200#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
201
202static void s3c2443_irq_cam_mask(struct irq_data *data)
203{
204 s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
205}
206
207static void s3c2443_irq_cam_unmask(struct irq_data *data)
208{
209 s3c_irqsub_unmask(data->irq, INTMSK_CAM);
210}
211
212static void s3c2443_irq_cam_ack(struct irq_data *data)
213{
214 s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
215}
216
217static struct irq_chip s3c2443_irq_cam = {
218 .irq_mask = s3c2443_irq_cam_mask,
219 .irq_unmask = s3c2443_irq_cam_unmask,
220 .irq_ack = s3c2443_irq_cam_ack,
221};
222
223/* IRQ initialisation code */
224
225static int __init s3c2443_add_sub(unsigned int base,
226 void (*demux)(unsigned int,
227 struct irq_desc *),
228 struct irq_chip *chip,
229 unsigned int start, unsigned int end)
230{
231 unsigned int irqno;
232
233 irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
234 irq_set_chained_handler(base, demux);
235
236 for (irqno = start; irqno <= end; irqno++) {
237 irq_set_chip_and_handler(irqno, chip, handle_level_irq);
238 set_irq_flags(irqno, IRQF_VALID);
239 }
240
241 return 0;
242}
243
244static int __init s3c2443_irq_add(struct device *dev,
245 struct subsys_interface *sif)
246{
247 printk("S3C2443: IRQ Support\n");
248
249 s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
250 IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
251
252 s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
253 IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
254
255 s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
256 &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
257
258 s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
259 &s3c2443_irq_uart3,
260 IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
261
262 s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
263 &s3c2443_irq_wdtac97,
264 IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
265
266 return 0;
267}
268
269static struct subsys_interface s3c2443_irq_interface = {
270 .name = "s3c2443_irq",
271 .subsys = &s3c2443_subsys,
272 .add_dev = s3c2443_irq_add,
273};
274
275static int __init s3c2443_irq_init(void)
276{
277 return subsys_interface_register(&s3c2443_irq_interface);
278}
279
280arch_initcall(s3c2443_irq_init);
281