kernel-ark/arch/alpha/kernel/irq_pyxis.c
Thomas Gleixner 44377f622e alpha: remove obsolete hw_interrupt_type
The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) have
been kept around for migration reasons.  After more than two years it's
time to remove them finally.

This patch cleans up one of the remaining users.  When all such patches
hit mainline we can remove the defines and typedefs finally.

Impact: cleanup

Convert the last remaining users to struct irq_chip and remove the
define.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Henderson <rth@twiddle.net>

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-06-16 19:47:46 -07:00

128 lines
2.5 KiB
C

/*
* linux/arch/alpha/kernel/irq_pyxis.c
*
* Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
*
* IRQ Code common to all PYXIS core logic chips.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/core_cia.h>
#include "proto.h"
#include "irq_impl.h"
/* Note mask bit is true for ENABLED irqs. */
static unsigned long cached_irq_mask;
static inline void
pyxis_update_irq_hw(unsigned long mask)
{
*(vulp)PYXIS_INT_MASK = mask;
mb();
*(vulp)PYXIS_INT_MASK;
}
static inline void
pyxis_enable_irq(unsigned int irq)
{
pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
}
static void
pyxis_disable_irq(unsigned int irq)
{
pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
}
static unsigned int
pyxis_startup_irq(unsigned int irq)
{
pyxis_enable_irq(irq);
return 0;
}
static void
pyxis_end_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
pyxis_enable_irq(irq);
}
static void
pyxis_mask_and_ack_irq(unsigned int irq)
{
unsigned long bit = 1UL << (irq - 16);
unsigned long mask = cached_irq_mask &= ~bit;
/* Disable the interrupt. */
*(vulp)PYXIS_INT_MASK = mask;
wmb();
/* Ack PYXIS PCI interrupt. */
*(vulp)PYXIS_INT_REQ = bit;
mb();
/* Re-read to force both writes. */
*(vulp)PYXIS_INT_MASK;
}
static struct irq_chip pyxis_irq_type = {
.typename = "PYXIS",
.startup = pyxis_startup_irq,
.shutdown = pyxis_disable_irq,
.enable = pyxis_enable_irq,
.disable = pyxis_disable_irq,
.ack = pyxis_mask_and_ack_irq,
.end = pyxis_end_irq,
};
void
pyxis_device_interrupt(unsigned long vector)
{
unsigned long pld;
unsigned int i;
/* Read the interrupt summary register of PYXIS */
pld = *(vulp)PYXIS_INT_REQ;
pld &= cached_irq_mask;
/*
* Now for every possible bit set, work through them and call
* the appropriate interrupt handler.
*/
while (pld) {
i = ffz(~pld);
pld &= pld - 1; /* clear least bit set */
if (i == 7)
isa_device_interrupt(vector);
else
handle_irq(16+i);
}
}
void __init
init_pyxis_irqs(unsigned long ignore_mask)
{
long i;
*(vulp)PYXIS_INT_MASK = 0; /* disable all */
*(vulp)PYXIS_INT_REQ = -1; /* flush all */
mb();
/* Send -INTA pulses to clear any pending interrupts ...*/
*(vuip) CIA_IACK_SC;
for (i = 16; i < 48; ++i) {
if ((ignore_mask >> i) & 1)
continue;
irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
irq_desc[i].chip = &pyxis_irq_type;
}
setup_irq(16+7, &isa_cascade_irqaction);
}