Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 110117
b: refs/heads/master
c: d6478fa
h: refs/heads/master
i:
  110115: a5c67a0
v: v3
  • Loading branch information
David Howells authored and Linus Torvalds committed Oct 1, 2008
1 parent b336a5b commit 28fb3c3
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7ac9c1c24c0e68bdb89524e8c99e13fffcb2fcfb
refs/heads/master: d6478fad430e37148b56f642c87301ba72476675
71 changes: 45 additions & 26 deletions trunk/arch/mn10300/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,8 @@ EXPORT_SYMBOL(__mn10300_irq_enabled_epsw);
atomic_t irq_err_count;

/*
* MN10300 INTC controller operations
* MN10300 interrupt controller operations
*/
static void mn10300_cpupic_disable(unsigned int irq)
{
u16 tmp = GxICR(irq);
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
tmp = GxICR(irq);
}

static void mn10300_cpupic_enable(unsigned int irq)
{
u16 tmp = GxICR(irq);
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
tmp = GxICR(irq);
}

static void mn10300_cpupic_ack(unsigned int irq)
{
u16 tmp;
Expand All @@ -60,26 +46,54 @@ static void mn10300_cpupic_mask_ack(unsigned int irq)
static void mn10300_cpupic_unmask(unsigned int irq)
{
u16 tmp = GxICR(irq);
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
tmp = GxICR(irq);
}

static void mn10300_cpupic_end(unsigned int irq)
static void mn10300_cpupic_unmask_clear(unsigned int irq)
{
/* the MN10300 PIC latches its interrupt request bit, even after the
* device has ceased to assert its interrupt line and the interrupt
* channel has been disabled in the PIC, so for level-triggered
* interrupts we need to clear the request bit when we re-enable */
u16 tmp = GxICR(irq);
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
tmp = GxICR(irq);
}

static struct irq_chip mn10300_cpu_pic = {
.name = "cpu",
.disable = mn10300_cpupic_disable,
.enable = mn10300_cpupic_enable,
/*
* MN10300 PIC level-triggered IRQ handling.
*
* The PIC has no 'ACK' function per se. It is possible to clear individual
* channel latches, but each latch relatches whether or not the channel is
* masked, so we need to clear the latch when we unmask the channel.
*
* Also for this reason, we don't supply an ack() op (it's unused anyway if
* mask_ack() is provided), and mask_ack() just masks.
*/
static struct irq_chip mn10300_cpu_pic_level = {
.name = "cpu_l",
.disable = mn10300_cpupic_mask,
.enable = mn10300_cpupic_unmask_clear,
.ack = NULL,
.mask = mn10300_cpupic_mask,
.mask_ack = mn10300_cpupic_mask,
.unmask = mn10300_cpupic_unmask_clear,
};

/*
* MN10300 PIC edge-triggered IRQ handling.
*
* We use the latch clearing function of the PIC as the 'ACK' function.
*/
static struct irq_chip mn10300_cpu_pic_edge = {
.name = "cpu_e",
.disable = mn10300_cpupic_mask,
.enable = mn10300_cpupic_unmask,
.ack = mn10300_cpupic_ack,
.mask = mn10300_cpupic_mask,
.mask_ack = mn10300_cpupic_mask_ack,
.unmask = mn10300_cpupic_unmask,
.end = mn10300_cpupic_end,
};

/*
Expand Down Expand Up @@ -114,7 +128,8 @@ void set_intr_level(int irq, u16 level)
*/
void set_intr_postackable(int irq)
{
set_irq_handler(irq, handle_level_irq);
set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level,
handle_level_irq);
}

/*
Expand All @@ -126,8 +141,12 @@ void __init init_IRQ(void)

for (irq = 0; irq < NR_IRQS; irq++)
if (irq_desc[irq].chip == &no_irq_type)
set_irq_chip_and_handler(irq, &mn10300_cpu_pic,
handle_edge_irq);
/* due to the PIC latching interrupt requests, even
* when the IRQ is disabled, IRQ_PENDING is superfluous
* and we can use handle_level_irq() for edge-triggered
* interrupts */
set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge,
handle_level_irq);
unit_init_IRQ();
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mn10300/unit-asb2303/unit-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void __init unit_init_IRQ(void)
switch (GET_XIRQ_TRIGGER(extnum)) {
case XIRQ_TRIGGER_HILEVEL:
case XIRQ_TRIGGER_LOWLEVEL:
set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq);
set_intr_postackable(XIRQ2IRQ(extnum));
break;
default:
break;
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mn10300/unit-asb2305/unit-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void __init unit_init_IRQ(void)
switch (GET_XIRQ_TRIGGER(extnum)) {
case XIRQ_TRIGGER_HILEVEL:
case XIRQ_TRIGGER_LOWLEVEL:
set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq);
set_intr_postackable(XIRQ2IRQ(extnum));
break;
default:
break;
Expand Down

0 comments on commit 28fb3c3

Please sign in to comment.