diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-11 14:01:04 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-11 14:01:04 -0400 |
commit | 1cf02bbd51a1ff74a31f88b1f654243a4affef8d (patch) | |
tree | 6f7b43be22d6aeabe652d30e87b7c267c3cb9cbf /arch | |
parent | 805499a6d5d7b7fa8528170d1b2869ea88485f99 (diff) | |
parent | bd7e388035d3c80aab360f18d123eb2e06eda8d1 (diff) |
Merge branch 'samsung-irq' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc-2.6 into devel-stable
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-s3c64xx/irq.c | 7 | ||||
-rw-r--r-- | arch/arm/plat-s5p/irq-gpioint.c | 116 | ||||
-rw-r--r-- | arch/arm/plat-s5p/irq.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/irq-vic-timer.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-samsung/irq-uart.c | 83 | ||||
-rw-r--r-- | arch/arm/plat-samsung/irq-vic-timer.c | 69 |
6 files changed, 68 insertions, 215 deletions
diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c index 67a145d440f3..97660c8141ae 100644 --- a/arch/arm/mach-s3c64xx/irq.c +++ b/arch/arm/mach-s3c64xx/irq.c | |||
@@ -58,12 +58,7 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) | |||
58 | vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0); | 58 | vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0); |
59 | 59 | ||
60 | /* add the timer sub-irqs */ | 60 | /* add the timer sub-irqs */ |
61 | 61 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | |
62 | s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); | ||
63 | s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); | ||
64 | s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); | ||
65 | s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); | ||
66 | s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); | ||
67 | 62 | ||
68 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); | 63 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); |
69 | } | 64 | } |
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index cd6d67c8382a..135abda31c9a 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c | |||
@@ -41,72 +41,11 @@ struct s5p_gpioint_bank { | |||
41 | 41 | ||
42 | LIST_HEAD(banks); | 42 | LIST_HEAD(banks); |
43 | 43 | ||
44 | static int s5p_gpioint_get_offset(struct irq_data *data) | 44 | static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) |
45 | { | 45 | { |
46 | struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); | 46 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
47 | return data->irq - chip->irq_base; | 47 | struct irq_chip_type *ct = gc->chip_types; |
48 | } | 48 | unsigned int shift = (d->irq - gc->irq_base) << 2; |
49 | |||
50 | static void s5p_gpioint_ack(struct irq_data *data) | ||
51 | { | ||
52 | struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); | ||
53 | int group, offset, pend_offset; | ||
54 | unsigned int value; | ||
55 | |||
56 | group = chip->group; | ||
57 | offset = s5p_gpioint_get_offset(data); | ||
58 | pend_offset = REG_OFFSET(group); | ||
59 | |||
60 | value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); | ||
61 | value |= BIT(offset); | ||
62 | __raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset); | ||
63 | } | ||
64 | |||
65 | static void s5p_gpioint_mask(struct irq_data *data) | ||
66 | { | ||
67 | struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); | ||
68 | int group, offset, mask_offset; | ||
69 | unsigned int value; | ||
70 | |||
71 | group = chip->group; | ||
72 | offset = s5p_gpioint_get_offset(data); | ||
73 | mask_offset = REG_OFFSET(group); | ||
74 | |||
75 | value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
76 | value |= BIT(offset); | ||
77 | __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
78 | } | ||
79 | |||
80 | static void s5p_gpioint_unmask(struct irq_data *data) | ||
81 | { | ||
82 | struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); | ||
83 | int group, offset, mask_offset; | ||
84 | unsigned int value; | ||
85 | |||
86 | group = chip->group; | ||
87 | offset = s5p_gpioint_get_offset(data); | ||
88 | mask_offset = REG_OFFSET(group); | ||
89 | |||
90 | value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
91 | value &= ~BIT(offset); | ||
92 | __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
93 | } | ||
94 | |||
95 | static void s5p_gpioint_mask_ack(struct irq_data *data) | ||
96 | { | ||
97 | s5p_gpioint_mask(data); | ||
98 | s5p_gpioint_ack(data); | ||
99 | } | ||
100 | |||
101 | static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type) | ||
102 | { | ||
103 | struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); | ||
104 | int group, offset, con_offset; | ||
105 | unsigned int value; | ||
106 | |||
107 | group = chip->group; | ||
108 | offset = s5p_gpioint_get_offset(data); | ||
109 | con_offset = REG_OFFSET(group); | ||
110 | 49 | ||
111 | switch (type) { | 50 | switch (type) { |
112 | case IRQ_TYPE_EDGE_RISING: | 51 | case IRQ_TYPE_EDGE_RISING: |
@@ -130,23 +69,12 @@ static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type) | |||
130 | return -EINVAL; | 69 | return -EINVAL; |
131 | } | 70 | } |
132 | 71 | ||
133 | value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset); | 72 | gc->type_cache &= ~(0x7 << shift); |
134 | value &= ~(0x7 << (offset * 0x4)); | 73 | gc->type_cache |= type << shift; |
135 | value |= (type << (offset * 0x4)); | 74 | writel(gc->type_cache, gc->reg_base + ct->regs.type); |
136 | __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset); | ||
137 | |||
138 | return 0; | 75 | return 0; |
139 | } | 76 | } |
140 | 77 | ||
141 | static struct irq_chip s5p_gpioint = { | ||
142 | .name = "s5p_gpioint", | ||
143 | .irq_ack = s5p_gpioint_ack, | ||
144 | .irq_mask = s5p_gpioint_mask, | ||
145 | .irq_mask_ack = s5p_gpioint_mask_ack, | ||
146 | .irq_unmask = s5p_gpioint_unmask, | ||
147 | .irq_set_type = s5p_gpioint_set_type, | ||
148 | }; | ||
149 | |||
150 | static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | 78 | static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) |
151 | { | 79 | { |
152 | struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); | 80 | struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); |
@@ -179,9 +107,10 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | |||
179 | static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) | 107 | static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) |
180 | { | 108 | { |
181 | static int used_gpioint_groups = 0; | 109 | static int used_gpioint_groups = 0; |
182 | int irq, group = chip->group; | 110 | int group = chip->group; |
183 | int i; | ||
184 | struct s5p_gpioint_bank *bank = NULL; | 111 | struct s5p_gpioint_bank *bank = NULL; |
112 | struct irq_chip_generic *gc; | ||
113 | struct irq_chip_type *ct; | ||
185 | 114 | ||
186 | if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) | 115 | if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) |
187 | return -ENOMEM; | 116 | return -ENOMEM; |
@@ -211,19 +140,28 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) | |||
211 | * chained GPIO irq has been successfully registered, allocate new gpio | 140 | * chained GPIO irq has been successfully registered, allocate new gpio |
212 | * int group and assign irq nubmers | 141 | * int group and assign irq nubmers |
213 | */ | 142 | */ |
214 | |||
215 | chip->irq_base = S5P_GPIOINT_BASE + | 143 | chip->irq_base = S5P_GPIOINT_BASE + |
216 | used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; | 144 | used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; |
217 | used_gpioint_groups++; | 145 | used_gpioint_groups++; |
218 | 146 | ||
219 | bank->chips[group - bank->start] = chip; | 147 | bank->chips[group - bank->start] = chip; |
220 | for (i = 0; i < chip->chip.ngpio; i++) { | 148 | |
221 | irq = chip->irq_base + i; | 149 | gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, |
222 | irq_set_chip(irq, &s5p_gpioint); | 150 | (void __iomem *)GPIO_BASE(chip), |
223 | irq_set_handler_data(irq, chip); | 151 | handle_level_irq); |
224 | irq_set_handler(irq, handle_level_irq); | 152 | if (!gc) |
225 | set_irq_flags(irq, IRQF_VALID); | 153 | return -ENOMEM; |
226 | } | 154 | ct = gc->chip_types; |
155 | ct->chip.irq_ack = irq_gc_ack; | ||
156 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
157 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
158 | ct->chip.irq_set_type = s5p_gpioint_set_type, | ||
159 | ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group); | ||
160 | ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group); | ||
161 | ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group); | ||
162 | irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), | ||
163 | IRQ_GC_INIT_MASK_CACHE, | ||
164 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
227 | return 0; | 165 | return 0; |
228 | } | 166 | } |
229 | 167 | ||
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c index 5560b12035d1..a97c08957f49 100644 --- a/arch/arm/plat-s5p/irq.c +++ b/arch/arm/plat-s5p/irq.c | |||
@@ -64,11 +64,7 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic) | |||
64 | vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); | 64 | vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); | 67 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); |
68 | s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); | ||
69 | s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); | ||
70 | s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); | ||
71 | s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); | ||
72 | 68 | ||
73 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); | 69 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); |
74 | } | 70 | } |
diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h index a90b53431b5b..5b9c42fd32d7 100644 --- a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h +++ b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h | |||
@@ -10,4 +10,4 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer); | 13 | extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq); |
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 4d4e571af553..32582c0958e3 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c | |||
@@ -27,60 +27,6 @@ | |||
27 | /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] | 27 | /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] |
28 | * are consecutive when looking up the interrupt in the demux routines. | 28 | * are consecutive when looking up the interrupt in the demux routines. |
29 | */ | 29 | */ |
30 | |||
31 | static inline void __iomem *s3c_irq_uart_base(struct irq_data *data) | ||
32 | { | ||
33 | struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data); | ||
34 | return uirq->regs; | ||
35 | } | ||
36 | |||
37 | static inline unsigned int s3c_irq_uart_bit(unsigned int irq) | ||
38 | { | ||
39 | return irq & 3; | ||
40 | } | ||
41 | |||
42 | static void s3c_irq_uart_mask(struct irq_data *data) | ||
43 | { | ||
44 | void __iomem *regs = s3c_irq_uart_base(data); | ||
45 | unsigned int bit = s3c_irq_uart_bit(data->irq); | ||
46 | u32 reg; | ||
47 | |||
48 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
49 | reg |= (1 << bit); | ||
50 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
51 | } | ||
52 | |||
53 | static void s3c_irq_uart_maskack(struct irq_data *data) | ||
54 | { | ||
55 | void __iomem *regs = s3c_irq_uart_base(data); | ||
56 | unsigned int bit = s3c_irq_uart_bit(data->irq); | ||
57 | u32 reg; | ||
58 | |||
59 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
60 | reg |= (1 << bit); | ||
61 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
62 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | ||
63 | } | ||
64 | |||
65 | static void s3c_irq_uart_unmask(struct irq_data *data) | ||
66 | { | ||
67 | void __iomem *regs = s3c_irq_uart_base(data); | ||
68 | unsigned int bit = s3c_irq_uart_bit(data->irq); | ||
69 | u32 reg; | ||
70 | |||
71 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
72 | reg &= ~(1 << bit); | ||
73 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
74 | } | ||
75 | |||
76 | static void s3c_irq_uart_ack(struct irq_data *data) | ||
77 | { | ||
78 | void __iomem *regs = s3c_irq_uart_base(data); | ||
79 | unsigned int bit = s3c_irq_uart_bit(data->irq); | ||
80 | |||
81 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | ||
82 | } | ||
83 | |||
84 | static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | 30 | static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) |
85 | { | 31 | { |
86 | struct s3c_uart_irq *uirq = desc->irq_data.handler_data; | 32 | struct s3c_uart_irq *uirq = desc->irq_data.handler_data; |
@@ -97,30 +43,25 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | |||
97 | generic_handle_irq(base + 3); | 43 | generic_handle_irq(base + 3); |
98 | } | 44 | } |
99 | 45 | ||
100 | static struct irq_chip s3c_irq_uart = { | ||
101 | .name = "s3c-uart", | ||
102 | .irq_mask = s3c_irq_uart_mask, | ||
103 | .irq_unmask = s3c_irq_uart_unmask, | ||
104 | .irq_mask_ack = s3c_irq_uart_maskack, | ||
105 | .irq_ack = s3c_irq_uart_ack, | ||
106 | }; | ||
107 | |||
108 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) | 46 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) |
109 | { | 47 | { |
110 | void __iomem *reg_base = uirq->regs; | 48 | void __iomem *reg_base = uirq->regs; |
111 | unsigned int irq; | 49 | struct irq_chip_generic *gc; |
112 | int offs; | 50 | struct irq_chip_type *ct; |
113 | 51 | ||
114 | /* mask all interrupts at the start. */ | 52 | /* mask all interrupts at the start. */ |
115 | __raw_writel(0xf, reg_base + S3C64XX_UINTM); | 53 | __raw_writel(0xf, reg_base + S3C64XX_UINTM); |
116 | 54 | ||
117 | for (offs = 0; offs < 3; offs++) { | 55 | gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, |
118 | irq = uirq->base_irq + offs; | 56 | handle_level_irq); |
119 | 57 | ct = gc->chip_types; | |
120 | irq_set_chip_and_handler(irq, &s3c_irq_uart, handle_level_irq); | 58 | ct->chip.irq_ack = irq_gc_ack; |
121 | irq_set_chip_data(irq, uirq); | 59 | ct->chip.irq_mask = irq_gc_mask_set_bit; |
122 | set_irq_flags(irq, IRQF_VALID); | 60 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; |
123 | } | 61 | ct->regs.ack = S3C64XX_UINTP; |
62 | ct->regs.mask = S3C64XX_UINTM; | ||
63 | irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE, | ||
64 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
124 | 65 | ||
125 | irq_set_handler_data(uirq->parent_irq, uirq); | 66 | irq_set_handler_data(uirq->parent_irq, uirq); |
126 | irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); | 67 | irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); |
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index d6ad66ab9290..a607546ddbd0 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c | |||
@@ -28,60 +28,43 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) | |||
28 | } | 28 | } |
29 | 29 | ||
30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | 30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ |
31 | 31 | static void s3c_irq_timer_ack(struct irq_data *d) | |
32 | static void s3c_irq_timer_mask(struct irq_data *data) | ||
33 | { | ||
34 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
35 | u32 mask = (u32)data->chip_data; | ||
36 | |||
37 | reg &= 0x1f; /* mask out pending interrupts */ | ||
38 | reg &= ~mask; | ||
39 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
40 | } | ||
41 | |||
42 | static void s3c_irq_timer_unmask(struct irq_data *data) | ||
43 | { | 32 | { |
44 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | 33 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
45 | u32 mask = (u32)data->chip_data; | 34 | u32 mask = (1 << 5) << (d->irq - gc->irq_base); |
46 | 35 | ||
47 | reg &= 0x1f; /* mask out pending interrupts */ | 36 | irq_reg_writel(mask | gc->mask_cache, gc->reg_base); |
48 | reg |= mask; | ||
49 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
50 | } | 37 | } |
51 | 38 | ||
52 | static void s3c_irq_timer_ack(struct irq_data *data) | ||
53 | { | ||
54 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
55 | u32 mask = (u32)data->chip_data; | ||
56 | |||
57 | reg &= 0x1f; | ||
58 | reg |= mask << 5; | ||
59 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
60 | } | ||
61 | |||
62 | static struct irq_chip s3c_irq_timer = { | ||
63 | .name = "s3c-timer", | ||
64 | .irq_mask = s3c_irq_timer_mask, | ||
65 | .irq_unmask = s3c_irq_timer_unmask, | ||
66 | .irq_ack = s3c_irq_timer_ack, | ||
67 | }; | ||
68 | |||
69 | /** | 39 | /** |
70 | * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ | 40 | * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ |
71 | * @parent_irq: The parent IRQ on the VIC for the timer. | 41 | * @num: Number of timers to initialize |
72 | * @timer_irq: The IRQ to be used for the timer. | 42 | * @timer_irq: Base IRQ number to be used for the timers. |
73 | * | 43 | * |
74 | * Register the necessary IRQ chaining and support for the timer IRQs | 44 | * Register the necessary IRQ chaining and support for the timer IRQs |
75 | * chained of the VIC. | 45 | * chained of the VIC. |
76 | */ | 46 | */ |
77 | void __init s3c_init_vic_timer_irq(unsigned int parent_irq, | 47 | void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) |
78 | unsigned int timer_irq) | ||
79 | { | 48 | { |
49 | unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC, | ||
50 | IRQ_TIMER3_VIC, IRQ_TIMER4_VIC }; | ||
51 | struct irq_chip_generic *s3c_tgc; | ||
52 | struct irq_chip_type *ct; | ||
53 | unsigned int i; | ||
80 | 54 | ||
81 | irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer); | 55 | s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, |
82 | irq_set_handler_data(parent_irq, (void *)timer_irq); | 56 | S3C64XX_TINT_CSTAT, handle_level_irq); |
57 | ct = s3c_tgc->chip_types; | ||
58 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | ||
59 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | ||
60 | ct->chip.irq_ack = s3c_irq_timer_ack; | ||
61 | irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | ||
62 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
63 | /* Clear the upper bits of the mask_cache*/ | ||
64 | s3c_tgc->mask_cache &= 0x1f; | ||
83 | 65 | ||
84 | irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq); | 66 | for (i = 0; i < num; i++, timer_irq++) { |
85 | irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); | 67 | irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer); |
86 | set_irq_flags(timer_irq, IRQF_VALID); | 68 | irq_set_handler_data(pirq[i], (void *)timer_irq); |
69 | } | ||
87 | } | 70 | } |