^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Code to handle IP32 IRQs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2000 Harald Koerfgen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2001 Keith M Wesolowski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel_stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/irq_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/ip32/crime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/ip32/mace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/ip32/ip32_ints.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* issue a PIO read to make sure no PIO writes are pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static inline void flush_crime_bus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) crime->control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static inline void flush_mace_bus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mace->perif.ctrl.misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * O2 irq map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * IP0 -> software (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * IP1 -> software (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * IP3 -> (irq1) X unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * IP4 -> (irq2) X unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * IP5 -> (irq3) X unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * IP6 -> (irq4) X unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * IP7 -> (irq5) 7 CPU count/compare timer (system timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * crime: (C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * CRIME_INT_STAT 31:0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * 0 -> 8 Video in 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * 1 -> 9 Video in 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * 2 -> 10 Video out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * 3 -> 11 Mace ethernet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * 4 -> S SuperIO sub-interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * 5 -> M Miscellaneous sub-interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * 6 -> A Audio sub-interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * 7 -> 15 PCI bridge errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * 8 -> 16 PCI SCSI aic7xxx 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * 9 -> 17 PCI SCSI aic7xxx 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * 10 -> 18 PCI slot 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * 11 -> 19 unused (PCI slot 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * 12 -> 20 unused (PCI slot 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * 13 -> 21 unused (PCI shared 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * 14 -> 22 unused (PCI shared 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * 15 -> 23 unused (PCI shared 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * 16 -> 24 GBE0 (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * 17 -> 25 GBE1 (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * 18 -> 26 GBE2 (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * 19 -> 27 GBE3 (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * 20 -> 28 CPU errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * 21 -> 29 Memory errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * 22 -> 30 RE empty edge (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * 23 -> 31 RE full edge (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * 24 -> 32 RE idle edge (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * 25 -> 33 RE empty level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * 26 -> 34 RE full level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * 27 -> 35 RE idle level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * 28 -> 36 unused (software 0) (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * 29 -> 37 unused (software 1) (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * 31 -> 39 VICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * S, M, A: Use the MACE ISA interrupt register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * MACE_ISA_INT_STAT 31:0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * 0-7 -> 40-47 Audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * 8 -> 48 RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * 9 -> 49 Keyboard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * 10 -> X Keyboard polled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * 11 -> 51 Mouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * 12 -> X Mouse polled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * 13-15 -> 53-55 Count/compare timers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * 16-19 -> 56-59 Parallel (16 E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * 20-25 -> 60-62 Serial 1 (22 E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * 26-31 -> 66-71 Serial 2 (28 E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * different IRQ map than IRIX uses, but that's OK as Linux irq handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * is quite different anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Some initial interrupts to set up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * This is for pure CRIME interrupts - ie not MACE. The advantage?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * We get to split the register in half and do faster lookups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static uint64_t crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline void crime_enable_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int bit = d->irq - CRIME_IRQ_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) crime_mask |= 1 << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline void crime_disable_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned int bit = d->irq - CRIME_IRQ_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) crime_mask &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) flush_crime_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static struct irq_chip crime_level_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .name = "IP32 CRIME",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .irq_mask = crime_disable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .irq_unmask = crime_enable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void crime_edge_mask_and_ack_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int bit = d->irq - CRIME_IRQ_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) uint64_t crime_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Edge triggered interrupts must be cleared. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) crime_int = crime->hard_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) crime_int &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) crime->hard_int = crime_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) crime_disable_irq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct irq_chip crime_edge_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .name = "IP32 CRIME",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .irq_ack = crime_edge_mask_and_ack_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .irq_mask = crime_disable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .irq_mask_ack = crime_edge_mask_and_ack_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .irq_unmask = crime_enable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * This is for MACE PCI interrupts. We can decrease bus traffic by masking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * as close to the source as possible. This also means we can take the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * next chunk of the CRIME register in one piece.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static unsigned long macepci_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static void enable_macepci_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mace->pci.control = macepci_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void disable_macepci_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) flush_crime_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mace->pci.control = macepci_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) flush_mace_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct irq_chip ip32_macepci_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .name = "IP32 MACE PCI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .irq_mask = disable_macepci_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .irq_unmask = enable_macepci_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* This is used for MACE ISA interrupts. That means bits 4-6 in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * CRIME register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define MACEISA_AUDIO_INT (MACEISA_AUDIO_SW_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) MACEISA_AUDIO_SC_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) MACEISA_AUDIO1_DMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) MACEISA_AUDIO1_OF_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) MACEISA_AUDIO2_DMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) MACEISA_AUDIO2_MERR_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) MACEISA_AUDIO3_DMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) MACEISA_AUDIO3_MERR_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define MACEISA_MISC_INT (MACEISA_RTC_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) MACEISA_KEYB_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) MACEISA_KEYB_POLL_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MACEISA_MOUSE_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) MACEISA_MOUSE_POLL_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) MACEISA_TIMER0_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) MACEISA_TIMER1_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) MACEISA_TIMER2_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define MACEISA_SUPERIO_INT (MACEISA_PARALLEL_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) MACEISA_PAR_CTXA_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) MACEISA_PAR_CTXB_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) MACEISA_PAR_MERR_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) MACEISA_SERIAL1_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) MACEISA_SERIAL1_TDMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) MACEISA_SERIAL1_TDMAPR_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) MACEISA_SERIAL1_TDMAME_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) MACEISA_SERIAL1_RDMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) MACEISA_SERIAL1_RDMAOR_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) MACEISA_SERIAL2_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) MACEISA_SERIAL2_TDMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) MACEISA_SERIAL2_TDMAPR_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) MACEISA_SERIAL2_TDMAME_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) MACEISA_SERIAL2_RDMAT_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) MACEISA_SERIAL2_RDMAOR_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static unsigned long maceisa_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void enable_maceisa_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned int crime_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) pr_debug("maceisa enable: %u\n", d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) switch (d->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) crime_int = MACE_AUDIO_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) crime_int = MACE_MISC_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) crime_int = MACE_SUPERIO_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) pr_debug("crime_int %08x enabled\n", crime_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) crime_mask |= crime_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mace->perif.ctrl.imask = maceisa_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void disable_maceisa_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned int crime_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!(maceisa_mask & MACEISA_AUDIO_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) crime_int |= MACE_AUDIO_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!(maceisa_mask & MACEISA_MISC_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) crime_int |= MACE_MISC_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!(maceisa_mask & MACEISA_SUPERIO_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) crime_int |= MACE_SUPERIO_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) crime_mask &= ~crime_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) flush_crime_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mace->perif.ctrl.imask = maceisa_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) flush_mace_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void mask_and_ack_maceisa_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned long mace_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* edge triggered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mace_int = mace->perif.ctrl.istat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mace->perif.ctrl.istat = mace_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) disable_maceisa_irq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static struct irq_chip ip32_maceisa_level_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .name = "IP32 MACE ISA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .irq_mask = disable_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .irq_unmask = enable_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static struct irq_chip ip32_maceisa_edge_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .name = "IP32 MACE ISA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .irq_ack = mask_and_ack_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .irq_mask = disable_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .irq_mask_ack = mask_and_ack_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .irq_unmask = enable_maceisa_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* This is used for regular non-ISA, non-PCI MACE interrupts. That means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * bits 0-3 and 7 in the CRIME register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void enable_mace_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) unsigned int bit = d->irq - CRIME_IRQ_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) crime_mask |= (1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static void disable_mace_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned int bit = d->irq - CRIME_IRQ_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) crime_mask &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) crime->imask = crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) flush_crime_bus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static struct irq_chip ip32_mace_interrupt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .name = "IP32 MACE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .irq_mask = disable_mace_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .irq_unmask = enable_mace_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void ip32_unknown_interrupt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) printk("Unknown interrupt occurred!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) printk("cp0_status: %08x\n", read_c0_status());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) printk("cp0_cause: %08x\n", read_c0_cause());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) printk("CRIME intr mask: %016lx\n", crime->imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) printk("CRIME intr status: %016lx\n", crime->istat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) printk("CRIME hardware intr register: %016lx\n", crime->hard_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) printk("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) printk("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) printk("MACE PCI control register: %08x\n", mace->pci.control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) printk("Register dump:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) show_regs(get_irq_regs());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) printk("Please mail this report to linux-mips@linux-mips.org\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) printk("Spinning...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) while(1) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* CRIME 1.1 appears to deliver all interrupts to this one pin. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* change this to loop over all edge-triggered irqs, exception masked out ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static void ip32_irq0(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) uint64_t crime_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * Sanity check interrupt numbering enum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * chained.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) crime_int = crime->istat & crime_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* crime sometime delivers spurious interrupts, ignore them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (unlikely(crime_int == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (crime_int & CRIME_MACEISA_INT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned long mace_int = mace->perif.ctrl.istat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) pr_debug("*irq %u*\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) do_IRQ(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void ip32_irq1(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ip32_unknown_interrupt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void ip32_irq2(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ip32_unknown_interrupt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static void ip32_irq3(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ip32_unknown_interrupt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void ip32_irq4(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ip32_unknown_interrupt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void ip32_irq5(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) do_IRQ(MIPS_CPU_IRQ_BASE + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) asmlinkage void plat_irq_dispatch(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) unsigned int pending = read_c0_status() & read_c0_cause();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (likely(pending & IE_IRQ0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ip32_irq0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else if (unlikely(pending & IE_IRQ1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ip32_irq1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) else if (unlikely(pending & IE_IRQ2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ip32_irq2();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) else if (unlikely(pending & IE_IRQ3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ip32_irq3();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else if (unlikely(pending & IE_IRQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ip32_irq4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else if (likely(pending & IE_IRQ5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ip32_irq5();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) void __init arch_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* Install our interrupt handler, then clear and disable all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * CRIME and MACE interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) crime->imask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) crime->hard_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) crime->soft_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) mace->perif.ctrl.istat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mace->perif.ctrl.imask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) mips_cpu_irq_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) switch (irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) &ip32_mace_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) handle_level_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) "level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) &ip32_macepci_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) handle_level_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) "level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case CRIME_CPUERR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case CRIME_MEMERR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) &crime_level_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) handle_level_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) "level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case CRIME_VICE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) &crime_edge_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) handle_edge_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) "edge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) case MACEISA_PARALLEL_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) case MACEISA_SERIAL1_TDMAPR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case MACEISA_SERIAL2_TDMAPR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) &ip32_maceisa_edge_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) handle_edge_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) "edge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) irq_set_chip_and_handler_name(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) &ip32_maceisa_level_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) handle_level_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) "level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (request_irq(CRIME_MEMERR_IRQ, crime_memerr_intr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) "CRIME memory error", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) pr_err("Failed to register CRIME memory error interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (request_irq(CRIME_CPUERR_IRQ, crime_cpuerr_intr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) "CRIME CPU error", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) pr_err("Failed to register CRIME CPU error interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) change_c0_status(ST0_IM, ALLINTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }