diff options
-rw-r--r-- | arch/arm/mach-s3c2410/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/s3c2412-irq.c | 130 |
4 files changed, 138 insertions, 2 deletions
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 273e05f2b8de..0eadec916214 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o | |||
28 | 28 | ||
29 | # S3C2412 support | 29 | # S3C2412 support |
30 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o | 30 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o |
31 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o | ||
31 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o | 32 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o |
32 | 33 | ||
33 | # | 34 | # |
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 6822dc7f7799..cd6139b35999 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
@@ -86,7 +86,7 @@ unsigned long s3c_irqwake_intmask = 0xffffffffL; | |||
86 | unsigned long s3c_irqwake_eintallow = 0x0000fff0L; | 86 | unsigned long s3c_irqwake_eintallow = 0x0000fff0L; |
87 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; | 87 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; |
88 | 88 | ||
89 | static int | 89 | int |
90 | s3c_irq_wake(unsigned int irqno, unsigned int state) | 90 | s3c_irq_wake(unsigned int irqno, unsigned int state) |
91 | { | 91 | { |
92 | unsigned long irqbit = 1 << (irqno - IRQ_EINT0); | 92 | unsigned long irqbit = 1 << (irqno - IRQ_EINT0); |
@@ -260,7 +260,7 @@ s3c_irqext_unmask(unsigned int irqno) | |||
260 | s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); | 260 | s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); |
261 | } | 261 | } |
262 | 262 | ||
263 | static int | 263 | int |
264 | s3c_irqext_type(unsigned int irq, unsigned int type) | 264 | s3c_irqext_type(unsigned int irq, unsigned int type) |
265 | { | 265 | { |
266 | void __iomem *extint_reg; | 266 | void __iomem *extint_reg; |
diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h index 4abf0ca14e00..f7cc4c983de5 100644 --- a/arch/arm/mach-s3c2410/irq.h +++ b/arch/arm/mach-s3c2410/irq.h | |||
@@ -97,3 +97,8 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) | |||
97 | __raw_writel(parentmask, S3C2410_INTPND); | 97 | __raw_writel(parentmask, S3C2410_INTPND); |
98 | } | 98 | } |
99 | } | 99 | } |
100 | |||
101 | /* exported for use in arch/arm/mach-s3c2410 */ | ||
102 | |||
103 | extern int s3c_irq_wake(unsigned int irqno, unsigned int state); | ||
104 | extern int s3c_irqext_type(unsigned int irq, unsigned int type); | ||
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c new file mode 100644 index 000000000000..c80ec93dfea9 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2412-irq.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* linux/arch/arm/mach-s3c2412/s3c2412-irq.c | ||
2 | * | ||
3 | * Copyright (c) 2006 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/ptrace.h> | ||
27 | #include <linux/sysdev.h> | ||
28 | |||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/io.h> | ||
32 | |||
33 | #include <asm/mach/irq.h> | ||
34 | |||
35 | #include <asm/arch/regs-irq.h> | ||
36 | #include <asm/arch/regs-gpio.h> | ||
37 | |||
38 | #include "cpu.h" | ||
39 | #include "irq.h" | ||
40 | |||
41 | /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by | ||
42 | * having them turn up in both the INT* and the EINT* registers. Whilst | ||
43 | * both show the status, they both now need to be acked when the IRQs | ||
44 | * go off. | ||
45 | */ | ||
46 | |||
47 | static void | ||
48 | s3c2412_irq_mask(unsigned int irqno) | ||
49 | { | ||
50 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | ||
51 | unsigned long mask; | ||
52 | |||
53 | mask = __raw_readl(S3C2410_INTMSK); | ||
54 | __raw_writel(mask | bitval, S3C2410_INTMSK); | ||
55 | |||
56 | mask = __raw_readl(S3C2412_EINTMASK); | ||
57 | __raw_writel(mask | bitval, S3C2412_EINTMASK); | ||
58 | } | ||
59 | |||
60 | static inline void | ||
61 | s3c2412_irq_ack(unsigned int irqno) | ||
62 | { | ||
63 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | ||
64 | |||
65 | __raw_writel(bitval, S3C2412_EINTPEND); | ||
66 | __raw_writel(bitval, S3C2410_SRCPND); | ||
67 | __raw_writel(bitval, S3C2410_INTPND); | ||
68 | } | ||
69 | |||
70 | static inline void | ||
71 | s3c2412_irq_maskack(unsigned int irqno) | ||
72 | { | ||
73 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | ||
74 | unsigned long mask; | ||
75 | |||
76 | mask = __raw_readl(S3C2410_INTMSK); | ||
77 | __raw_writel(mask|bitval, S3C2410_INTMSK); | ||
78 | |||
79 | mask = __raw_readl(S3C2412_EINTMASK); | ||
80 | __raw_writel(mask | bitval, S3C2412_EINTMASK); | ||
81 | |||
82 | __raw_writel(bitval, S3C2412_EINTPEND); | ||
83 | __raw_writel(bitval, S3C2410_SRCPND); | ||
84 | __raw_writel(bitval, S3C2410_INTPND); | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | s3c2412_irq_unmask(unsigned int irqno) | ||
89 | { | ||
90 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | ||
91 | unsigned long mask; | ||
92 | |||
93 | mask = __raw_readl(S3C2412_EINTMASK); | ||
94 | __raw_writel(mask & ~bitval, S3C2412_EINTMASK); | ||
95 | |||
96 | mask = __raw_readl(S3C2410_INTMSK); | ||
97 | __raw_writel(mask & ~bitval, S3C2410_INTMSK); | ||
98 | } | ||
99 | |||
100 | static struct irqchip s3c2412_irq_eint0t4 = { | ||
101 | .ack = s3c2412_irq_ack, | ||
102 | .mask = s3c2412_irq_mask, | ||
103 | .unmask = s3c2412_irq_unmask, | ||
104 | .set_wake = s3c_irq_wake, | ||
105 | .set_type = s3c_irqext_type, | ||
106 | }; | ||
107 | |||
108 | static int s3c2412_irq_add(struct sys_device *sysdev) | ||
109 | { | ||
110 | unsigned int irqno; | ||
111 | |||
112 | for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { | ||
113 | set_irq_chip(irqno, &s3c2412_irq_eint0t4); | ||
114 | set_irq_handler(irqno, do_edge_IRQ); | ||
115 | set_irq_flags(irqno, IRQF_VALID); | ||
116 | } | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static struct sysdev_driver s3c2412_irq_driver = { | ||
122 | .add = s3c2412_irq_add, | ||
123 | }; | ||
124 | |||
125 | static int s3c2412_irq_init(void) | ||
126 | { | ||
127 | return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_irq_driver); | ||
128 | } | ||
129 | |||
130 | arch_initcall(s3c2412_irq_init); | ||