Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Code to handle IP32 IRQs
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  *
0008  * Copyright (C) 2000 Harald Koerfgen
0009  * Copyright (C) 2001 Keith M Wesolowski
0010  */
0011 #include <linux/init.h>
0012 #include <linux/kernel_stat.h>
0013 #include <linux/types.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/bitops.h>
0017 #include <linux/kernel.h>
0018 #include <linux/mm.h>
0019 #include <linux/random.h>
0020 #include <linux/sched.h>
0021 #include <linux/sched/debug.h>
0022 
0023 #include <asm/irq_cpu.h>
0024 #include <asm/mipsregs.h>
0025 #include <asm/signal.h>
0026 #include <asm/time.h>
0027 #include <asm/ip32/crime.h>
0028 #include <asm/ip32/mace.h>
0029 #include <asm/ip32/ip32_ints.h>
0030 
0031 /* issue a PIO read to make sure no PIO writes are pending */
0032 static inline void flush_crime_bus(void)
0033 {
0034     crime->control;
0035 }
0036 
0037 static inline void flush_mace_bus(void)
0038 {
0039     mace->perif.ctrl.misc;
0040 }
0041 
0042 /*
0043  * O2 irq map
0044  *
0045  * IP0 -> software (ignored)
0046  * IP1 -> software (ignored)
0047  * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
0048  * IP3 -> (irq1) X unknown
0049  * IP4 -> (irq2) X unknown
0050  * IP5 -> (irq3) X unknown
0051  * IP6 -> (irq4) X unknown
0052  * IP7 -> (irq5) 7 CPU count/compare timer (system timer)
0053  *
0054  * crime: (C)
0055  *
0056  * CRIME_INT_STAT 31:0:
0057  *
0058  * 0  ->  8  Video in 1
0059  * 1  ->  9 Video in 2
0060  * 2  -> 10  Video out
0061  * 3  -> 11  Mace ethernet
0062  * 4  -> S  SuperIO sub-interrupt
0063  * 5  -> M  Miscellaneous sub-interrupt
0064  * 6  -> A  Audio sub-interrupt
0065  * 7  -> 15  PCI bridge errors
0066  * 8  -> 16  PCI SCSI aic7xxx 0
0067  * 9  -> 17 PCI SCSI aic7xxx 1
0068  * 10 -> 18 PCI slot 0
0069  * 11 -> 19 unused (PCI slot 1)
0070  * 12 -> 20 unused (PCI slot 2)
0071  * 13 -> 21 unused (PCI shared 0)
0072  * 14 -> 22 unused (PCI shared 1)
0073  * 15 -> 23 unused (PCI shared 2)
0074  * 16 -> 24 GBE0 (E)
0075  * 17 -> 25 GBE1 (E)
0076  * 18 -> 26 GBE2 (E)
0077  * 19 -> 27 GBE3 (E)
0078  * 20 -> 28 CPU errors
0079  * 21 -> 29 Memory errors
0080  * 22 -> 30 RE empty edge (E)
0081  * 23 -> 31 RE full edge (E)
0082  * 24 -> 32 RE idle edge (E)
0083  * 25 -> 33 RE empty level
0084  * 26 -> 34 RE full level
0085  * 27 -> 35 RE idle level
0086  * 28 -> 36 unused (software 0) (E)
0087  * 29 -> 37 unused (software 1) (E)
0088  * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E)
0089  * 31 -> 39 VICE
0090  *
0091  * S, M, A: Use the MACE ISA interrupt register
0092  * MACE_ISA_INT_STAT 31:0
0093  *
0094  * 0-7 -> 40-47 Audio
0095  * 8 -> 48 RTC
0096  * 9 -> 49 Keyboard
0097  * 10 -> X Keyboard polled
0098  * 11 -> 51 Mouse
0099  * 12 -> X Mouse polled
0100  * 13-15 -> 53-55 Count/compare timers
0101  * 16-19 -> 56-59 Parallel (16 E)
0102  * 20-25 -> 60-62 Serial 1 (22 E)
0103  * 26-31 -> 66-71 Serial 2 (28 E)
0104  *
0105  * Note that this means IRQs 12-14, 50, and 52 do not exist.  This is a
0106  * different IRQ map than IRIX uses, but that's OK as Linux irq handling
0107  * is quite different anyway.
0108  */
0109 
0110 /* Some initial interrupts to set up */
0111 extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
0112 extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
0113 
0114 /*
0115  * This is for pure CRIME interrupts - ie not MACE.  The advantage?
0116  * We get to split the register in half and do faster lookups.
0117  */
0118 
0119 static uint64_t crime_mask;
0120 
0121 static inline void crime_enable_irq(struct irq_data *d)
0122 {
0123     unsigned int bit = d->irq - CRIME_IRQ_BASE;
0124 
0125     crime_mask |= 1 << bit;
0126     crime->imask = crime_mask;
0127 }
0128 
0129 static inline void crime_disable_irq(struct irq_data *d)
0130 {
0131     unsigned int bit = d->irq - CRIME_IRQ_BASE;
0132 
0133     crime_mask &= ~(1 << bit);
0134     crime->imask = crime_mask;
0135     flush_crime_bus();
0136 }
0137 
0138 static struct irq_chip crime_level_interrupt = {
0139     .name       = "IP32 CRIME",
0140     .irq_mask   = crime_disable_irq,
0141     .irq_unmask = crime_enable_irq,
0142 };
0143 
0144 static void crime_edge_mask_and_ack_irq(struct irq_data *d)
0145 {
0146     unsigned int bit = d->irq - CRIME_IRQ_BASE;
0147     uint64_t crime_int;
0148 
0149     /* Edge triggered interrupts must be cleared. */
0150     crime_int = crime->hard_int;
0151     crime_int &= ~(1 << bit);
0152     crime->hard_int = crime_int;
0153 
0154     crime_disable_irq(d);
0155 }
0156 
0157 static struct irq_chip crime_edge_interrupt = {
0158     .name       = "IP32 CRIME",
0159     .irq_ack    = crime_edge_mask_and_ack_irq,
0160     .irq_mask   = crime_disable_irq,
0161     .irq_mask_ack   = crime_edge_mask_and_ack_irq,
0162     .irq_unmask = crime_enable_irq,
0163 };
0164 
0165 /*
0166  * This is for MACE PCI interrupts.  We can decrease bus traffic by masking
0167  * as close to the source as possible.  This also means we can take the
0168  * next chunk of the CRIME register in one piece.
0169  */
0170 
0171 static unsigned long macepci_mask;
0172 
0173 static void enable_macepci_irq(struct irq_data *d)
0174 {
0175     macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
0176     mace->pci.control = macepci_mask;
0177     crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
0178     crime->imask = crime_mask;
0179 }
0180 
0181 static void disable_macepci_irq(struct irq_data *d)
0182 {
0183     crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
0184     crime->imask = crime_mask;
0185     flush_crime_bus();
0186     macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
0187     mace->pci.control = macepci_mask;
0188     flush_mace_bus();
0189 }
0190 
0191 static struct irq_chip ip32_macepci_interrupt = {
0192     .name = "IP32 MACE PCI",
0193     .irq_mask = disable_macepci_irq,
0194     .irq_unmask = enable_macepci_irq,
0195 };
0196 
0197 /* This is used for MACE ISA interrupts.  That means bits 4-6 in the
0198  * CRIME register.
0199  */
0200 
0201 #define MACEISA_AUDIO_INT   (MACEISA_AUDIO_SW_INT |     \
0202                  MACEISA_AUDIO_SC_INT |     \
0203                  MACEISA_AUDIO1_DMAT_INT |  \
0204                  MACEISA_AUDIO1_OF_INT |    \
0205                  MACEISA_AUDIO2_DMAT_INT |  \
0206                  MACEISA_AUDIO2_MERR_INT |  \
0207                  MACEISA_AUDIO3_DMAT_INT |  \
0208                  MACEISA_AUDIO3_MERR_INT)
0209 #define MACEISA_MISC_INT    (MACEISA_RTC_INT |      \
0210                  MACEISA_KEYB_INT |     \
0211                  MACEISA_KEYB_POLL_INT |    \
0212                  MACEISA_MOUSE_INT |        \
0213                  MACEISA_MOUSE_POLL_INT |   \
0214                  MACEISA_TIMER0_INT |       \
0215                  MACEISA_TIMER1_INT |       \
0216                  MACEISA_TIMER2_INT)
0217 #define MACEISA_SUPERIO_INT (MACEISA_PARALLEL_INT |     \
0218                  MACEISA_PAR_CTXA_INT |     \
0219                  MACEISA_PAR_CTXB_INT |     \
0220                  MACEISA_PAR_MERR_INT |     \
0221                  MACEISA_SERIAL1_INT |      \
0222                  MACEISA_SERIAL1_TDMAT_INT |    \
0223                  MACEISA_SERIAL1_TDMAPR_INT |   \
0224                  MACEISA_SERIAL1_TDMAME_INT |   \
0225                  MACEISA_SERIAL1_RDMAT_INT |    \
0226                  MACEISA_SERIAL1_RDMAOR_INT |   \
0227                  MACEISA_SERIAL2_INT |      \
0228                  MACEISA_SERIAL2_TDMAT_INT |    \
0229                  MACEISA_SERIAL2_TDMAPR_INT |   \
0230                  MACEISA_SERIAL2_TDMAME_INT |   \
0231                  MACEISA_SERIAL2_RDMAT_INT |    \
0232                  MACEISA_SERIAL2_RDMAOR_INT)
0233 
0234 static unsigned long maceisa_mask;
0235 
0236 static void enable_maceisa_irq(struct irq_data *d)
0237 {
0238     unsigned int crime_int = 0;
0239 
0240     pr_debug("maceisa enable: %u\n", d->irq);
0241 
0242     switch (d->irq) {
0243     case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
0244         crime_int = MACE_AUDIO_INT;
0245         break;
0246     case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
0247         crime_int = MACE_MISC_INT;
0248         break;
0249     case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
0250         crime_int = MACE_SUPERIO_INT;
0251         break;
0252     }
0253     pr_debug("crime_int %08x enabled\n", crime_int);
0254     crime_mask |= crime_int;
0255     crime->imask = crime_mask;
0256     maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
0257     mace->perif.ctrl.imask = maceisa_mask;
0258 }
0259 
0260 static void disable_maceisa_irq(struct irq_data *d)
0261 {
0262     unsigned int crime_int = 0;
0263 
0264     maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
0265     if (!(maceisa_mask & MACEISA_AUDIO_INT))
0266         crime_int |= MACE_AUDIO_INT;
0267     if (!(maceisa_mask & MACEISA_MISC_INT))
0268         crime_int |= MACE_MISC_INT;
0269     if (!(maceisa_mask & MACEISA_SUPERIO_INT))
0270         crime_int |= MACE_SUPERIO_INT;
0271     crime_mask &= ~crime_int;
0272     crime->imask = crime_mask;
0273     flush_crime_bus();
0274     mace->perif.ctrl.imask = maceisa_mask;
0275     flush_mace_bus();
0276 }
0277 
0278 static void mask_and_ack_maceisa_irq(struct irq_data *d)
0279 {
0280     unsigned long mace_int;
0281 
0282     /* edge triggered */
0283     mace_int = mace->perif.ctrl.istat;
0284     mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
0285     mace->perif.ctrl.istat = mace_int;
0286 
0287     disable_maceisa_irq(d);
0288 }
0289 
0290 static struct irq_chip ip32_maceisa_level_interrupt = {
0291     .name       = "IP32 MACE ISA",
0292     .irq_mask   = disable_maceisa_irq,
0293     .irq_unmask = enable_maceisa_irq,
0294 };
0295 
0296 static struct irq_chip ip32_maceisa_edge_interrupt = {
0297     .name       = "IP32 MACE ISA",
0298     .irq_ack    = mask_and_ack_maceisa_irq,
0299     .irq_mask   = disable_maceisa_irq,
0300     .irq_mask_ack   = mask_and_ack_maceisa_irq,
0301     .irq_unmask = enable_maceisa_irq,
0302 };
0303 
0304 /* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
0305  * bits 0-3 and 7 in the CRIME register.
0306  */
0307 
0308 static void enable_mace_irq(struct irq_data *d)
0309 {
0310     unsigned int bit = d->irq - CRIME_IRQ_BASE;
0311 
0312     crime_mask |= (1 << bit);
0313     crime->imask = crime_mask;
0314 }
0315 
0316 static void disable_mace_irq(struct irq_data *d)
0317 {
0318     unsigned int bit = d->irq - CRIME_IRQ_BASE;
0319 
0320     crime_mask &= ~(1 << bit);
0321     crime->imask = crime_mask;
0322     flush_crime_bus();
0323 }
0324 
0325 static struct irq_chip ip32_mace_interrupt = {
0326     .name = "IP32 MACE",
0327     .irq_mask = disable_mace_irq,
0328     .irq_unmask = enable_mace_irq,
0329 };
0330 
0331 static void ip32_unknown_interrupt(void)
0332 {
0333     printk("Unknown interrupt occurred!\n");
0334     printk("cp0_status: %08x\n", read_c0_status());
0335     printk("cp0_cause: %08x\n", read_c0_cause());
0336     printk("CRIME intr mask: %016lx\n", crime->imask);
0337     printk("CRIME intr status: %016lx\n", crime->istat);
0338     printk("CRIME hardware intr register: %016lx\n", crime->hard_int);
0339     printk("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
0340     printk("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
0341     printk("MACE PCI control register: %08x\n", mace->pci.control);
0342 
0343     printk("Register dump:\n");
0344     show_regs(get_irq_regs());
0345 
0346     printk("Please mail this report to linux-mips@vger.kernel.org\n");
0347     printk("Spinning...");
0348     while(1) ;
0349 }
0350 
0351 /* CRIME 1.1 appears to deliver all interrupts to this one pin. */
0352 /* change this to loop over all edge-triggered irqs, exception masked out ones */
0353 static void ip32_irq0(void)
0354 {
0355     uint64_t crime_int;
0356     int irq = 0;
0357 
0358     /*
0359      * Sanity check interrupt numbering enum.
0360      * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy
0361      * chained.
0362      */
0363     BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
0364     BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
0365 
0366     crime_int = crime->istat & crime_mask;
0367 
0368     /* crime sometime delivers spurious interrupts, ignore them */
0369     if (unlikely(crime_int == 0))
0370         return;
0371 
0372     irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
0373 
0374     if (crime_int & CRIME_MACEISA_INT_MASK) {
0375         unsigned long mace_int = mace->perif.ctrl.istat;
0376         irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
0377     }
0378 
0379     pr_debug("*irq %u*\n", irq);
0380     do_IRQ(irq);
0381 }
0382 
0383 static void ip32_irq1(void)
0384 {
0385     ip32_unknown_interrupt();
0386 }
0387 
0388 static void ip32_irq2(void)
0389 {
0390     ip32_unknown_interrupt();
0391 }
0392 
0393 static void ip32_irq3(void)
0394 {
0395     ip32_unknown_interrupt();
0396 }
0397 
0398 static void ip32_irq4(void)
0399 {
0400     ip32_unknown_interrupt();
0401 }
0402 
0403 static void ip32_irq5(void)
0404 {
0405     do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0406 }
0407 
0408 asmlinkage void plat_irq_dispatch(void)
0409 {
0410     unsigned int pending = read_c0_status() & read_c0_cause();
0411 
0412     if (likely(pending & IE_IRQ0))
0413         ip32_irq0();
0414     else if (unlikely(pending & IE_IRQ1))
0415         ip32_irq1();
0416     else if (unlikely(pending & IE_IRQ2))
0417         ip32_irq2();
0418     else if (unlikely(pending & IE_IRQ3))
0419         ip32_irq3();
0420     else if (unlikely(pending & IE_IRQ4))
0421         ip32_irq4();
0422     else if (likely(pending & IE_IRQ5))
0423         ip32_irq5();
0424 }
0425 
0426 void __init arch_init_irq(void)
0427 {
0428     unsigned int irq;
0429 
0430     /* Install our interrupt handler, then clear and disable all
0431      * CRIME and MACE interrupts. */
0432     crime->imask = 0;
0433     crime->hard_int = 0;
0434     crime->soft_int = 0;
0435     mace->perif.ctrl.istat = 0;
0436     mace->perif.ctrl.imask = 0;
0437 
0438     mips_cpu_irq_init();
0439     for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
0440         switch (irq) {
0441         case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
0442             irq_set_chip_and_handler_name(irq,
0443                               &ip32_mace_interrupt,
0444                               handle_level_irq,
0445                               "level");
0446             break;
0447 
0448         case MACEPCI_SCSI0_IRQ ...  MACEPCI_SHARED2_IRQ:
0449             irq_set_chip_and_handler_name(irq,
0450                               &ip32_macepci_interrupt,
0451                               handle_level_irq,
0452                               "level");
0453             break;
0454 
0455         case CRIME_CPUERR_IRQ:
0456         case CRIME_MEMERR_IRQ:
0457             irq_set_chip_and_handler_name(irq,
0458                               &crime_level_interrupt,
0459                               handle_level_irq,
0460                               "level");
0461             break;
0462 
0463         case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
0464         case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
0465         case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
0466         case CRIME_VICE_IRQ:
0467             irq_set_chip_and_handler_name(irq,
0468                               &crime_edge_interrupt,
0469                               handle_edge_irq,
0470                               "edge");
0471             break;
0472 
0473         case MACEISA_PARALLEL_IRQ:
0474         case MACEISA_SERIAL1_TDMAPR_IRQ:
0475         case MACEISA_SERIAL2_TDMAPR_IRQ:
0476             irq_set_chip_and_handler_name(irq,
0477                               &ip32_maceisa_edge_interrupt,
0478                               handle_edge_irq,
0479                               "edge");
0480             break;
0481 
0482         default:
0483             irq_set_chip_and_handler_name(irq,
0484                               &ip32_maceisa_level_interrupt,
0485                               handle_level_irq,
0486                               "level");
0487             break;
0488         }
0489     }
0490     if (request_irq(CRIME_MEMERR_IRQ, crime_memerr_intr, 0,
0491             "CRIME memory error", NULL))
0492         pr_err("Failed to register CRIME memory error interrupt\n");
0493     if (request_irq(CRIME_CPUERR_IRQ, crime_cpuerr_intr, 0,
0494             "CRIME CPU error", NULL))
0495         pr_err("Failed to register CRIME CPU error interrupt\n");
0496 
0497 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
0498     change_c0_status(ST0_IM, ALLINTS);
0499 }