Skip to content

Commit

Permalink
sh: add interrupt ack code to sh4a
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yoshihiro Shimoda authored and Paul Mundt committed Jul 28, 2008
1 parent f12ae6b commit 6bdfb22
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 28 deletions.
31 changes: 23 additions & 8 deletions arch/sh/kernel/cpu/irq/intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct intc_desc_int {
#endif

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];
#endif

Expand Down Expand Up @@ -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)
{
struct intc_desc_int *d = get_intc_desc(irq);
Expand All @@ -244,8 +244,23 @@ static void intc_mask_ack(unsigned int irq)

if (handle) {
addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
ctrl_inb(addr);
ctrl_outb(0x3f ^ set_field(0, 1, handle), addr);
switch (_INTC_FN(handle)) {
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
Expand Down Expand Up @@ -466,7 +481,7 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
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,
struct intc_desc_int *d,
intc_enum enum_id)
Expand Down Expand Up @@ -601,7 +616,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */
d->chip.mask(irq);

#ifdef CONFIG_CPU_SH3
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs)
ack_handle[irq] = intc_ack_data(desc, d, enum_id);
#endif
Expand Down Expand Up @@ -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->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;
#endif
d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
Expand Down Expand Up @@ -676,7 +691,7 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.mask_ack = intc_disable;
d->chip.set_type = intc_set_sense;

#ifdef CONFIG_CPU_SH3
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs) {
for (i = 0; i < desc->nr_ack_regs; i++)
k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
Expand Down
10 changes: 8 additions & 2 deletions arch/sh/kernel/cpu/sh4a/setup-sh7366.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_desc, "sh7366", vectors, groups,
mask_registers, prio_registers, sense_registers);
static struct intc_mask_reg ack_registers[] __initdata = {
{ 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)
{
Expand Down
10 changes: 8 additions & 2 deletions arch/sh/kernel/cpu/sh4a/setup-sh7722.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups,
mask_registers, prio_registers, sense_registers);
static struct intc_mask_reg ack_registers[] __initdata = {
{ 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)
{
Expand Down
10 changes: 8 additions & 2 deletions arch/sh/kernel/cpu/sh4a/setup-sh7723.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,14 @@ static struct intc_sense_reg sense_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_desc, "sh7723", vectors, groups,
mask_registers, prio_registers, sense_registers);
static struct intc_mask_reg ack_registers[] __initdata = {
{ 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)
{
Expand Down
11 changes: 8 additions & 3 deletions arch/sh/kernel/cpu/sh4a/setup-sh7763.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers);
static struct intc_mask_reg irq_ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ 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 */
Expand Down
11 changes: 8 additions & 3 deletions arch/sh/kernel/cpu/sh4a/setup-sh7780.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,14 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers);
static struct intc_mask_reg irq_ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ 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 */

Expand Down
17 changes: 11 additions & 6 deletions arch/sh/kernel/cpu/sh4a/setup-sh7785.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,18 @@ static struct intc_sense_reg sense_registers[] __initdata = {
IRQ4, IRQ5, IRQ6, IRQ7 } },
};

static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123,
NULL, mask_registers, prio_registers,
sense_registers);
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ 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,
NULL, mask_registers, prio_registers,
sense_registers);
static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7785-irq4567",
vectors_irq4567, NULL, mask_registers,
prio_registers, sense_registers, ack_registers);

/* External interrupt pins in IRL mode */

Expand Down
4 changes: 2 additions & 2 deletions include/asm-sh/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ struct intc_desc {
struct intc_sense_reg *sense_regs;
unsigned int nr_sense_regs;
char *name;
#ifdef CONFIG_CPU_SH3
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
struct intc_mask_reg *ack_regs;
unsigned int nr_ack_regs;
#endif
Expand All @@ -95,7 +95,7 @@ struct intc_desc symbol __initdata = { \
chipname, \
}

#ifdef CONFIG_CPU_SH3
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs, ack_regs) \
struct intc_desc symbol __initdata = { \
Expand Down

0 comments on commit 6bdfb22

Please sign in to comment.