Commit 6bdfb22a authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Paul Mundt

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: default avatarYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent f12ae6bc
...@@ -62,7 +62,7 @@ struct intc_desc_int { ...@@ -62,7 +62,7 @@ struct intc_desc_int {
#endif #endif
static unsigned int intc_prio_level[NR_IRQS]; /* for now */ static unsigned int intc_prio_level[NR_IRQS]; /* for now */
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
static unsigned long ack_handle[NR_IRQS]; static unsigned long ack_handle[NR_IRQS];
#endif #endif
...@@ -231,7 +231,7 @@ static void intc_disable(unsigned int irq) ...@@ -231,7 +231,7 @@ static void intc_disable(unsigned int irq)
} }
} }
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
static void intc_mask_ack(unsigned int irq) static void intc_mask_ack(unsigned int irq)
{ {
struct intc_desc_int *d = get_intc_desc(irq); struct intc_desc_int *d = get_intc_desc(irq);
...@@ -244,8 +244,23 @@ static void intc_mask_ack(unsigned int irq) ...@@ -244,8 +244,23 @@ static void intc_mask_ack(unsigned int irq)
if (handle) { if (handle) {
addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
ctrl_inb(addr); switch (_INTC_FN(handle)) {
ctrl_outb(0x3f ^ set_field(0, 1, handle), addr); case REG_FN_MODIFY_BASE + 0: /* 8bit */
ctrl_inb(addr);
ctrl_outb(0xff ^ set_field(0, 1, handle), addr);
break;
case REG_FN_MODIFY_BASE + 1: /* 16bit */
ctrl_inw(addr);
ctrl_outw(0xffff ^ set_field(0, 1, handle), addr);
break;
case REG_FN_MODIFY_BASE + 3: /* 32bit */
ctrl_inl(addr);
ctrl_outl(0xffffffff ^ set_field(0, 1, handle), addr);
break;
default:
BUG();
break;
}
} }
} }
#endif #endif
...@@ -466,7 +481,7 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, ...@@ -466,7 +481,7 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
return 0; return 0;
} }
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
static unsigned int __init intc_ack_data(struct intc_desc *desc, static unsigned int __init intc_ack_data(struct intc_desc *desc,
struct intc_desc_int *d, struct intc_desc_int *d,
intc_enum enum_id) intc_enum enum_id)
...@@ -601,7 +616,7 @@ static void __init intc_register_irq(struct intc_desc *desc, ...@@ -601,7 +616,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */ /* irq should be disabled by default */
d->chip.mask(irq); d->chip.mask(irq);
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs) if (desc->ack_regs)
ack_handle[irq] = intc_ack_data(desc, d, enum_id); ack_handle[irq] = intc_ack_data(desc, d, enum_id);
#endif #endif
...@@ -635,7 +650,7 @@ void __init register_intc_controller(struct intc_desc *desc) ...@@ -635,7 +650,7 @@ void __init register_intc_controller(struct intc_desc *desc)
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
#endif #endif
d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
...@@ -676,7 +691,7 @@ void __init register_intc_controller(struct intc_desc *desc) ...@@ -676,7 +691,7 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.mask_ack = intc_disable; d->chip.mask_ack = intc_disable;
d->chip.set_type = intc_set_sense; d->chip.set_type = intc_set_sense;
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs) { if (desc->ack_regs) {
for (i = 0; i < desc->nr_ack_regs; i++) for (i = 0; i < desc->nr_ack_regs; i++)
k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
......
...@@ -163,8 +163,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { ...@@ -163,8 +163,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_desc, "sh7366", vectors, groups, static struct intc_mask_reg ack_registers[] __initdata = {
mask_registers, prio_registers, sense_registers); { 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc, "sh7366", vectors, groups,
mask_registers, prio_registers, sense_registers,
ack_registers);
void __init plat_irq_setup(void) void __init plat_irq_setup(void)
{ {
......
...@@ -229,8 +229,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { ...@@ -229,8 +229,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, static struct intc_mask_reg ack_registers[] __initdata = {
mask_registers, prio_registers, sense_registers); { 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups,
mask_registers, prio_registers, sense_registers,
ack_registers);
void __init plat_irq_setup(void) void __init plat_irq_setup(void)
{ {
......
...@@ -326,8 +326,14 @@ static struct intc_sense_reg sense_registers[] __initdata = { ...@@ -326,8 +326,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_desc, "sh7723", vectors, groups, static struct intc_mask_reg ack_registers[] __initdata = {
mask_registers, prio_registers, sense_registers); { 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups,
mask_registers, prio_registers, sense_registers,
ack_registers);
void __init plat_irq_setup(void) void __init plat_irq_setup(void)
{ {
......
...@@ -296,9 +296,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = { ...@@ -296,9 +296,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } }, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors, static struct intc_mask_reg irq_ack_registers[] __initdata = {
NULL, irq_mask_registers, irq_prio_registers, { 0xffd00024, 0, 32, /* INTREQ */
irq_sense_registers); { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers, irq_ack_registers);
/* External interrupt pins in IRL mode */ /* External interrupt pins in IRL mode */
......
...@@ -217,9 +217,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = { ...@@ -217,9 +217,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } }, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, static struct intc_mask_reg irq_ack_registers[] __initdata = {
NULL, irq_mask_registers, irq_prio_registers, { 0xffd00024, 0, 32, /* INTREQ */
irq_sense_registers); { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers, irq_ack_registers);
/* External interrupt pins in IRL mode */ /* External interrupt pins in IRL mode */
......
...@@ -238,13 +238,18 @@ static struct intc_sense_reg sense_registers[] __initdata = { ...@@ -238,13 +238,18 @@ static struct intc_sense_reg sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } }, IRQ4, IRQ5, IRQ6, IRQ7 } },
}; };
static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, static struct intc_mask_reg ack_registers[] __initdata = {
NULL, mask_registers, prio_registers, { 0xffd00024, 0, 32, /* INTREQ */
sense_registers); { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7785-irq0123",
vectors_irq0123, NULL, mask_registers,
prio_registers, sense_registers, ack_registers);
static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7785-irq4567",
NULL, mask_registers, prio_registers, vectors_irq4567, NULL, mask_registers,
sense_registers); prio_registers, sense_registers, ack_registers);
/* External interrupt pins in IRL mode */ /* External interrupt pins in IRL mode */
......
...@@ -79,7 +79,7 @@ struct intc_desc { ...@@ -79,7 +79,7 @@ struct intc_desc {
struct intc_sense_reg *sense_regs; struct intc_sense_reg *sense_regs;
unsigned int nr_sense_regs; unsigned int nr_sense_regs;
char *name; char *name;
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
struct intc_mask_reg *ack_regs; struct intc_mask_reg *ack_regs;
unsigned int nr_ack_regs; unsigned int nr_ack_regs;
#endif #endif
...@@ -95,7 +95,7 @@ struct intc_desc symbol __initdata = { \ ...@@ -95,7 +95,7 @@ struct intc_desc symbol __initdata = { \
chipname, \ chipname, \
} }
#ifdef CONFIG_CPU_SH3 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ #define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs, ack_regs) \ mask_regs, prio_regs, sense_regs, ack_regs) \
struct intc_desc symbol __initdata = { \ struct intc_desc symbol __initdata = { \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment