/* issue a PIO read to make sure no PIO writes are pending */
static void inline flush_crime_bus(void)
{
- crime->control;
+ volatile unsigned long junk = crime->control;
}
static void inline flush_mace_bus(void)
{
- mace->perif.ctrl.misc;
+ volatile unsigned long junk = mace->perif.ctrl.misc;
}
#undef DEBUG_IRQ
extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id,
struct pt_regs *regs);
-struct irqaction memerr_irq = { crime_memerr_intr, IRQF_DISABLED,
+struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
CPU_MASK_NONE, "CRIME memory error", NULL, NULL };
-struct irqaction cpuerr_irq = { crime_cpuerr_intr, IRQF_DISABLED,
+struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
+extern void ip32_handle_int(void);
+
/*
* For interrupts wired from a single device to the CPU. Only the clock
* uses this it seems, which is IRQ 0 and IP7.
#define shutdown_cpu_irq disable_cpu_irq
#define mask_and_ack_cpu_irq disable_cpu_irq
-static struct irq_chip ip32_cpu_interrupt = {
+static struct hw_interrupt_type ip32_cpu_interrupt = {
.typename = "IP32 CPU",
.startup = startup_cpu_irq,
.shutdown = shutdown_cpu_irq,
#define shutdown_crime_irq disable_crime_irq
-static struct irq_chip ip32_crime_interrupt = {
+static struct hw_interrupt_type ip32_crime_interrupt = {
.typename = "IP32 CRIME",
.startup = startup_crime_irq,
.shutdown = shutdown_crime_irq,
#define shutdown_macepci_irq disable_macepci_irq
#define mask_and_ack_macepci_irq disable_macepci_irq
-static struct irq_chip ip32_macepci_interrupt = {
+static struct hw_interrupt_type ip32_macepci_interrupt = {
.typename = "IP32 MACE PCI",
.startup = startup_macepci_irq,
.shutdown = shutdown_macepci_irq,
#define shutdown_maceisa_irq disable_maceisa_irq
-static struct irq_chip ip32_maceisa_interrupt = {
+static struct hw_interrupt_type ip32_maceisa_interrupt = {
.typename = "IP32 MACE ISA",
.startup = startup_maceisa_irq,
.shutdown = shutdown_maceisa_irq,
#define shutdown_mace_irq disable_mace_irq
#define mask_and_ack_mace_irq disable_mace_irq
-static struct irq_chip ip32_mace_interrupt = {
+static struct hw_interrupt_type ip32_mace_interrupt = {
.typename = "IP32 MACE",
.startup = startup_mace_irq,
.shutdown = shutdown_mace_irq,
/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
/* change this to loop over all edge-triggered irqs, exception masked out ones */
-static void ip32_irq0(struct pt_regs *regs)
+void ip32_irq0(struct pt_regs *regs)
{
uint64_t crime_int;
int irq = 0;
crime_int = crime->istat & crime_mask;
- irq = __ffs(crime_int);
- crime_int = 1 << irq;
+ irq = ffs(crime_int);
+ crime_int = 1 << (irq - 1);
if (crime_int & CRIME_MACEISA_INT_MASK) {
unsigned long mace_int = mace->perif.ctrl.istat;
- irq = __ffs(mace_int & maceisa_mask) + 32;
+ irq = ffs(mace_int & maceisa_mask) + 32;
}
- irq++;
DBG("*irq %u*\n", irq);
do_IRQ(irq, regs);
}
-static void ip32_irq1(struct pt_regs *regs)
+void ip32_irq1(struct pt_regs *regs)
{
ip32_unknown_interrupt(regs);
}
-static void ip32_irq2(struct pt_regs *regs)
+void ip32_irq2(struct pt_regs *regs)
{
ip32_unknown_interrupt(regs);
}
-static void ip32_irq3(struct pt_regs *regs)
+void ip32_irq3(struct pt_regs *regs)
{
ip32_unknown_interrupt(regs);
}
-static void ip32_irq4(struct pt_regs *regs)
+void ip32_irq4(struct pt_regs *regs)
{
ip32_unknown_interrupt(regs);
}
-static void ip32_irq5(struct pt_regs *regs)
+void ip32_irq5(struct pt_regs *regs)
{
ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
}
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
-{
- unsigned int pending = read_c0_cause();
-
- if (likely(pending & IE_IRQ0))
- ip32_irq0(regs);
- else if (unlikely(pending & IE_IRQ1))
- ip32_irq1(regs);
- else if (unlikely(pending & IE_IRQ2))
- ip32_irq2(regs);
- else if (unlikely(pending & IE_IRQ3))
- ip32_irq3(regs);
- else if (unlikely(pending & IE_IRQ4))
- ip32_irq4(regs);
- else if (likely(pending & IE_IRQ5))
- ip32_irq5(regs);
-}
-
void __init arch_init_irq(void)
{
unsigned int irq;
crime->soft_int = 0;
mace->perif.ctrl.istat = 0;
mace->perif.ctrl.imask = 0;
+ set_except_vector(0, ip32_handle_int);
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
- struct irq_chip *controller;
+ hw_irq_controller *controller;
if (irq == IP32_R4K_TIMER_IRQ)
controller = &ip32_cpu_interrupt;
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 0;
- irq_desc[irq].chip = controller;
+ irq_desc[irq].handler = controller;
}
setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);