diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-10-21 09:06:57 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2008-12-15 16:52:51 -0500 |
commit | f982dc5321848ca6150a7a2c2bb3e28bddcf5ebe (patch) | |
tree | a854a69febfa17e3503da09d3c8d58384c678c82 /arch/arm/plat-s3c64xx/irq.c | |
parent | e550ae741663e4708dcdad3fc392db156189c77c (diff) |
[ARM] S3C64XX: Map timer memory and interrupts
Add the physical to virtual memory mapping and the
necessary interrupt demuxing for the PWM timer blocks.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/plat-s3c64xx/irq.c')
-rw-r--r-- | arch/arm/plat-s3c64xx/irq.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/arch/arm/plat-s3c64xx/irq.c b/arch/arm/plat-s3c64xx/irq.c index 308dc4198a17..1e6fa5c828c9 100644 --- a/arch/arm/plat-s3c64xx/irq.c +++ b/arch/arm/plat-s3c64xx/irq.c | |||
@@ -14,21 +14,106 @@ | |||
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
18 | 19 | ||
19 | #include <asm/hardware/vic.h> | 20 | #include <asm/hardware/vic.h> |
20 | #include <asm/irq.h> | ||
21 | 21 | ||
22 | #include <mach/map.h> | 22 | #include <mach/map.h> |
23 | #include <plat/regs-timer.h> | ||
23 | #include <plat/cpu.h> | 24 | #include <plat/cpu.h> |
24 | 25 | ||
26 | /* Timer interrupt handling */ | ||
27 | |||
28 | static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq) | ||
29 | { | ||
30 | generic_handle_irq(sub_irq); | ||
31 | } | ||
32 | |||
33 | static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc) | ||
34 | { | ||
35 | s3c_irq_demux_timer(irq, IRQ_TIMER0); | ||
36 | } | ||
37 | |||
38 | static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc) | ||
39 | { | ||
40 | s3c_irq_demux_timer(irq, IRQ_TIMER1); | ||
41 | } | ||
42 | |||
43 | static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc) | ||
44 | { | ||
45 | s3c_irq_demux_timer(irq, IRQ_TIMER2); | ||
46 | } | ||
47 | |||
48 | static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc) | ||
49 | { | ||
50 | s3c_irq_demux_timer(irq, IRQ_TIMER3); | ||
51 | } | ||
52 | |||
53 | static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc) | ||
54 | { | ||
55 | s3c_irq_demux_timer(irq, IRQ_TIMER4); | ||
56 | } | ||
57 | |||
58 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | ||
59 | |||
60 | static void s3c_irq_timer_mask(unsigned int irq) | ||
61 | { | ||
62 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
63 | |||
64 | reg &= 0x1f; /* mask out pending interrupts */ | ||
65 | reg &= ~(1 << (irq - IRQ_TIMER0)); | ||
66 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
67 | } | ||
68 | |||
69 | static void s3c_irq_timer_unmask(unsigned int irq) | ||
70 | { | ||
71 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
72 | |||
73 | reg &= 0x1f; /* mask out pending interrupts */ | ||
74 | reg |= 1 << (irq - IRQ_TIMER0); | ||
75 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
76 | } | ||
77 | |||
78 | static void s3c_irq_timer_ack(unsigned int irq) | ||
79 | { | ||
80 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
81 | |||
82 | reg &= 0x1f; | ||
83 | reg |= (1 << 5) << (irq - IRQ_TIMER0); | ||
84 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
85 | } | ||
86 | |||
87 | static struct irq_chip s3c_irq_timer = { | ||
88 | .name = "s3c-timer", | ||
89 | .mask = s3c_irq_timer_mask, | ||
90 | .unmask = s3c_irq_timer_unmask, | ||
91 | .ack = s3c_irq_timer_ack, | ||
92 | }; | ||
93 | |||
25 | void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) | 94 | void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) |
26 | { | 95 | { |
96 | int irq; | ||
97 | |||
27 | printk(KERN_INFO "%s: initialising interrupts\n", __func__); | 98 | printk(KERN_INFO "%s: initialising interrupts\n", __func__); |
28 | 99 | ||
29 | /* initialise the pair of VICs */ | 100 | /* initialise the pair of VICs */ |
30 | vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid); | 101 | vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid); |
31 | vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid); | 102 | vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid); |
103 | |||
104 | /* add the timer sub-irqs */ | ||
105 | |||
106 | set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0); | ||
107 | set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1); | ||
108 | set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2); | ||
109 | set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3); | ||
110 | set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4); | ||
111 | |||
112 | for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) { | ||
113 | set_irq_chip(irq, &s3c_irq_timer); | ||
114 | set_irq_handler(irq, handle_level_irq); | ||
115 | set_irq_flags(irq, IRQF_VALID); | ||
116 | } | ||
32 | } | 117 | } |
33 | 118 | ||
34 | 119 | ||