aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/irq
diff options
context:
space:
mode:
authorYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>2008-07-03 23:37:12 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-28 05:10:33 -0400
commit6bdfb22a8e1ffa37ae4ad35b87cb02958d1901e5 (patch)
treeafc8f27f1044be5787fb38d181292dd861f9a1c5 /arch/sh/kernel/cpu/irq
parentf12ae6bc4ad0054386b380dbf90e63617cd5ab92 (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>
Diffstat (limited to 'arch/sh/kernel/cpu/irq')
-rw-r--r--arch/sh/kernel/cpu/irq/intc.c31
1 files changed, 23 insertions, 8 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
64static unsigned int intc_prio_level[NR_IRQS]; /* for now */ 64static unsigned int intc_prio_level[NR_IRQS]; /* for now */
65#ifdef CONFIG_CPU_SH3 65#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
66static unsigned long ack_handle[NR_IRQS]; 66static 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)
235static void intc_mask_ack(unsigned int irq) 235static 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)
470static unsigned int __init intc_ack_data(struct intc_desc *desc, 485static 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);