linux/arch/mips/pmc-sierra/msp71xx/msp_irq.c
<<
>>
Prefs
   1/*
   2 * IRQ vector handles
   3 *
   4 * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/irq.h>
  14#include <linux/interrupt.h>
  15#include <linux/ptrace.h>
  16#include <linux/time.h>
  17
  18#include <asm/irq_cpu.h>
  19
  20#include <msp_int.h>
  21
  22extern void msp_int_handle(void);
  23
  24/* SLP bases systems */
  25extern void msp_slp_irq_init(void);
  26extern void msp_slp_irq_dispatch(void);
  27
  28/* CIC based systems */
  29extern void msp_cic_irq_init(void);
  30extern void msp_cic_irq_dispatch(void);
  31
  32/*
  33 * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
  34 * hierarchical system.  The first level are the direct MIPS interrupts
  35 * and are assigned the interrupt range 0-7.  The second level is the SLM
  36 * interrupt controller and is assigned the range 8-39.  The third level
  37 * comprises the Peripherial block, the PCI block, the PCI MSI block and
  38 * the SLP.  The PCI interrupts and the SLP errors are handled by the
  39 * relevant subsystems so the core interrupt code needs only concern
  40 * itself with the Peripheral block.  These are assigned interrupts in
  41 * the range 40-71.
  42 */
  43
  44asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
  45{
  46        u32 pending;
  47
  48        pending = read_c0_status() & read_c0_cause();
  49
  50        /*
  51         * jump to the correct interrupt routine
  52         * These are arranged in priority order and the timer
  53         * comes first!
  54         */
  55
  56#ifdef CONFIG_IRQ_MSP_CIC       /* break out the CIC stuff for now */
  57        if (pending & C_IRQ4)   /* do the peripherals first, that's the timer */
  58                msp_cic_irq_dispatch();
  59
  60        else if (pending & C_IRQ0)
  61                do_IRQ(MSP_INT_MAC0);
  62
  63        else if (pending & C_IRQ1)
  64                do_IRQ(MSP_INT_MAC1);
  65
  66        else if (pending & C_IRQ2)
  67                do_IRQ(MSP_INT_USB);
  68
  69        else if (pending & C_IRQ3)
  70                do_IRQ(MSP_INT_SAR);
  71
  72        else if (pending & C_IRQ5)
  73                do_IRQ(MSP_INT_SEC);
  74
  75#else
  76        if (pending & C_IRQ5)
  77                do_IRQ(MSP_INT_TIMER);
  78
  79        else if (pending & C_IRQ0)
  80                do_IRQ(MSP_INT_MAC0);
  81
  82        else if (pending & C_IRQ1)
  83                do_IRQ(MSP_INT_MAC1);
  84
  85        else if (pending & C_IRQ3)
  86                do_IRQ(MSP_INT_VE);
  87
  88        else if (pending & C_IRQ4)
  89                msp_slp_irq_dispatch();
  90#endif
  91
  92        else if (pending & C_SW0)       /* do software after hardware */
  93                do_IRQ(MSP_INT_SW0);
  94
  95        else if (pending & C_SW1)
  96                do_IRQ(MSP_INT_SW1);
  97}
  98
  99static struct irqaction cascade_msp = {
 100        .handler = no_action,
 101        .name    = "MSP cascade"
 102};
 103
 104
 105void __init arch_init_irq(void)
 106{
 107        /* initialize the 1st-level CPU based interrupt controller */
 108        mips_cpu_irq_init();
 109
 110#ifdef CONFIG_IRQ_MSP_CIC
 111        msp_cic_irq_init();
 112
 113        /* setup the cascaded interrupts */
 114        setup_irq(MSP_INT_CIC, &cascade_msp);
 115        setup_irq(MSP_INT_PER, &cascade_msp);
 116#else
 117        /* setup the 2nd-level SLP register based interrupt controller */
 118        msp_slp_irq_init();
 119
 120        /* setup the cascaded SLP/PER interrupts */
 121        setup_irq(MSP_INT_SLP, &cascade_msp);
 122        setup_irq(MSP_INT_PER, &cascade_msp);
 123#endif
 124}
 125
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.