diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2008-07-03 23:37:12 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-07-28 05:10:33 -0400 |
commit | 6bdfb22a8e1ffa37ae4ad35b87cb02958d1901e5 (patch) | |
tree | afc8f27f1044be5787fb38d181292dd861f9a1c5 | |
parent | f12ae6bc4ad0054386b380dbf90e63617cd5ab92 (diff) |
sh: add interrupt ack code to sh4a
This patch is based on interrupt acknowledge code for external
interrupt sources on sh3 processors and adds on sh4a processors.
Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc.c | 31 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 11 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 11 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 17 | ||||
-rw-r--r-- | include/asm-sh/hw_irq.h | 4 |
8 files changed, 76 insertions, 28 deletions
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index da5dae787888..8c70e201bde0 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c | |||
@@ -62,7 +62,7 @@ struct intc_desc_int { | |||
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | static unsigned int intc_prio_level[NR_IRQS]; /* for now */ | 64 | static unsigned int intc_prio_level[NR_IRQS]; /* for now */ |
65 | #ifdef CONFIG_CPU_SH3 | 65 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
66 | static unsigned long ack_handle[NR_IRQS]; | 66 | static unsigned long ack_handle[NR_IRQS]; |
67 | #endif | 67 | #endif |
68 | 68 | ||
@@ -231,7 +231,7 @@ static void intc_disable(unsigned int irq) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | #ifdef CONFIG_CPU_SH3 | 234 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
235 | static void intc_mask_ack(unsigned int irq) | 235 | static void intc_mask_ack(unsigned int irq) |
236 | { | 236 | { |
237 | struct intc_desc_int *d = get_intc_desc(irq); | 237 | struct intc_desc_int *d = get_intc_desc(irq); |
@@ -244,8 +244,23 @@ static void intc_mask_ack(unsigned int irq) | |||
244 | 244 | ||
245 | if (handle) { | 245 | if (handle) { |
246 | addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); | 246 | addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); |
247 | ctrl_inb(addr); | 247 | switch (_INTC_FN(handle)) { |
248 | ctrl_outb(0x3f ^ set_field(0, 1, handle), addr); | 248 | case REG_FN_MODIFY_BASE + 0: /* 8bit */ |
249 | ctrl_inb(addr); | ||
250 | ctrl_outb(0xff ^ set_field(0, 1, handle), addr); | ||
251 | break; | ||
252 | case REG_FN_MODIFY_BASE + 1: /* 16bit */ | ||
253 | ctrl_inw(addr); | ||
254 | ctrl_outw(0xffff ^ set_field(0, 1, handle), addr); | ||
255 | break; | ||
256 | case REG_FN_MODIFY_BASE + 3: /* 32bit */ | ||
257 | ctrl_inl(addr); | ||
258 | ctrl_outl(0xffffffff ^ set_field(0, 1, handle), addr); | ||
259 | break; | ||
260 | default: | ||
261 | BUG(); | ||
262 | break; | ||
263 | } | ||
249 | } | 264 | } |
250 | } | 265 | } |
251 | #endif | 266 | #endif |
@@ -466,7 +481,7 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, | |||
466 | return 0; | 481 | return 0; |
467 | } | 482 | } |
468 | 483 | ||
469 | #ifdef CONFIG_CPU_SH3 | 484 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
470 | static unsigned int __init intc_ack_data(struct intc_desc *desc, | 485 | static unsigned int __init intc_ack_data(struct intc_desc *desc, |
471 | struct intc_desc_int *d, | 486 | struct intc_desc_int *d, |
472 | intc_enum enum_id) | 487 | intc_enum enum_id) |
@@ -601,7 +616,7 @@ static void __init intc_register_irq(struct intc_desc *desc, | |||
601 | /* irq should be disabled by default */ | 616 | /* irq should be disabled by default */ |
602 | d->chip.mask(irq); | 617 | d->chip.mask(irq); |
603 | 618 | ||
604 | #ifdef CONFIG_CPU_SH3 | 619 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
605 | if (desc->ack_regs) | 620 | if (desc->ack_regs) |
606 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); | 621 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); |
607 | #endif | 622 | #endif |
@@ -635,7 +650,7 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
635 | d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; | 650 | d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; |
636 | d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; | 651 | d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; |
637 | 652 | ||
638 | #ifdef CONFIG_CPU_SH3 | 653 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
639 | d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; | 654 | d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; |
640 | #endif | 655 | #endif |
641 | d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); | 656 | d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); |
@@ -676,7 +691,7 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
676 | d->chip.mask_ack = intc_disable; | 691 | d->chip.mask_ack = intc_disable; |
677 | d->chip.set_type = intc_set_sense; | 692 | d->chip.set_type = intc_set_sense; |
678 | 693 | ||
679 | #ifdef CONFIG_CPU_SH3 | 694 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
680 | if (desc->ack_regs) { | 695 | if (desc->ack_regs) { |
681 | for (i = 0; i < desc->nr_ack_regs; i++) | 696 | for (i = 0; i < desc->nr_ack_regs; i++) |
682 | k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); | 697 | k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index f26b5cdad0d1..f97ea8e0acf5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c | |||
@@ -163,8 +163,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { | |||
163 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | 163 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static DECLARE_INTC_DESC(intc_desc, "sh7366", vectors, groups, | 166 | static struct intc_mask_reg ack_registers[] __initdata = { |
167 | mask_registers, prio_registers, sense_registers); | 167 | { 0xa4140024, 0, 8, /* INTREQ00 */ |
168 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
169 | }; | ||
170 | |||
171 | static DECLARE_INTC_DESC_ACK(intc_desc, "sh7366", vectors, groups, | ||
172 | mask_registers, prio_registers, sense_registers, | ||
173 | ack_registers); | ||
168 | 174 | ||
169 | void __init plat_irq_setup(void) | 175 | void __init plat_irq_setup(void) |
170 | { | 176 | { |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 62ebccf18b3c..d8617b669fad 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -229,8 +229,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { | |||
229 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | 229 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
230 | }; | 230 | }; |
231 | 231 | ||
232 | static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, | 232 | static struct intc_mask_reg ack_registers[] __initdata = { |
233 | mask_registers, prio_registers, sense_registers); | 233 | { 0xa4140024, 0, 8, /* INTREQ00 */ |
234 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
235 | }; | ||
236 | |||
237 | static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups, | ||
238 | mask_registers, prio_registers, sense_registers, | ||
239 | ack_registers); | ||
234 | 240 | ||
235 | void __init plat_irq_setup(void) | 241 | void __init plat_irq_setup(void) |
236 | { | 242 | { |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index a0470f2f5479..abd1ca03f39f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c | |||
@@ -326,8 +326,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { | |||
326 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | 326 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
327 | }; | 327 | }; |
328 | 328 | ||
329 | static DECLARE_INTC_DESC(intc_desc, "sh7723", vectors, groups, | 329 | static struct intc_mask_reg ack_registers[] __initdata = { |
330 | mask_registers, prio_registers, sense_registers); | 330 | { 0xa4140024, 0, 8, /* INTREQ00 */ |
331 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
332 | }; | ||
333 | |||
334 | static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups, | ||
335 | mask_registers, prio_registers, sense_registers, | ||
336 | ack_registers); | ||
331 | 337 | ||
332 | void __init plat_irq_setup(void) | 338 | void __init plat_irq_setup(void) |
333 | { | 339 | { |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 3b278df8a53b..3c5b629887a8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c | |||
@@ -296,9 +296,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = { | |||
296 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | 296 | IRQ4, IRQ5, IRQ6, IRQ7 } }, |
297 | }; | 297 | }; |
298 | 298 | ||
299 | static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors, | 299 | static struct intc_mask_reg irq_ack_registers[] __initdata = { |
300 | NULL, irq_mask_registers, irq_prio_registers, | 300 | { 0xffd00024, 0, 32, /* INTREQ */ |
301 | irq_sense_registers); | 301 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
302 | }; | ||
303 | |||
304 | static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors, | ||
305 | NULL, irq_mask_registers, irq_prio_registers, | ||
306 | irq_sense_registers, irq_ack_registers); | ||
302 | 307 | ||
303 | 308 | ||
304 | /* External interrupt pins in IRL mode */ | 309 | /* External interrupt pins in IRL mode */ |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 18dbbe23fea1..fb8200cc7440 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c | |||
@@ -217,9 +217,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = { | |||
217 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | 217 | IRQ4, IRQ5, IRQ6, IRQ7 } }, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, | 220 | static struct intc_mask_reg irq_ack_registers[] __initdata = { |
221 | NULL, irq_mask_registers, irq_prio_registers, | 221 | { 0xffd00024, 0, 32, /* INTREQ */ |
222 | irq_sense_registers); | 222 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
223 | }; | ||
224 | |||
225 | static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors, | ||
226 | NULL, irq_mask_registers, irq_prio_registers, | ||
227 | irq_sense_registers, irq_ack_registers); | ||
223 | 228 | ||
224 | /* External interrupt pins in IRL mode */ | 229 | /* External interrupt pins in IRL mode */ |
225 | 230 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 621e7329ec63..30baa63b24c8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c | |||
@@ -238,13 +238,18 @@ static struct intc_sense_reg sense_registers[] __initdata = { | |||
238 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | 238 | IRQ4, IRQ5, IRQ6, IRQ7 } }, |
239 | }; | 239 | }; |
240 | 240 | ||
241 | static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, | 241 | static struct intc_mask_reg ack_registers[] __initdata = { |
242 | NULL, mask_registers, prio_registers, | 242 | { 0xffd00024, 0, 32, /* INTREQ */ |
243 | sense_registers); | 243 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
244 | }; | ||
245 | |||
246 | static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7785-irq0123", | ||
247 | vectors_irq0123, NULL, mask_registers, | ||
248 | prio_registers, sense_registers, ack_registers); | ||
244 | 249 | ||
245 | static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, | 250 | static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7785-irq4567", |
246 | NULL, mask_registers, prio_registers, | 251 | vectors_irq4567, NULL, mask_registers, |
247 | sense_registers); | 252 | prio_registers, sense_registers, ack_registers); |
248 | 253 | ||
249 | /* External interrupt pins in IRL mode */ | 254 | /* External interrupt pins in IRL mode */ |
250 | 255 | ||
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 7438d1e21bc9..d557b00111bf 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h | |||
@@ -79,7 +79,7 @@ struct intc_desc { | |||
79 | struct intc_sense_reg *sense_regs; | 79 | struct intc_sense_reg *sense_regs; |
80 | unsigned int nr_sense_regs; | 80 | unsigned int nr_sense_regs; |
81 | char *name; | 81 | char *name; |
82 | #ifdef CONFIG_CPU_SH3 | 82 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
83 | struct intc_mask_reg *ack_regs; | 83 | struct intc_mask_reg *ack_regs; |
84 | unsigned int nr_ack_regs; | 84 | unsigned int nr_ack_regs; |
85 | #endif | 85 | #endif |
@@ -95,7 +95,7 @@ struct intc_desc symbol __initdata = { \ | |||
95 | chipname, \ | 95 | chipname, \ |
96 | } | 96 | } |
97 | 97 | ||
98 | #ifdef CONFIG_CPU_SH3 | 98 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) |
99 | #define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ | 99 | #define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ |
100 | mask_regs, prio_regs, sense_regs, ack_regs) \ | 100 | mask_regs, prio_regs, sense_regs, ack_regs) \ |
101 | struct intc_desc symbol __initdata = { \ | 101 | struct intc_desc symbol __initdata = { \ |