irq.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * IRQ vector handles
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
  9.  * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
  10.  *
  11.  */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/ioport.h>
  17. #include <asm/bootinfo.h>
  18. #include <asm/io.h>
  19. #include <asm/irq.h>
  20. #include <asm/mipsregs.h>
  21. #include <asm/system.h>
  22. #include <asm/cobalt/cobalt.h>
  23. /* Cobalt Exception handler */
  24. extern void cobalt_handle_int(void);
  25. /* Via masking routines */
  26. extern void unmask_irq(unsigned int irqr);
  27. extern void mask_irq(unsigned int irq);
  28. /*
  29.  * We have two types of interrupts that we handle, ones that come
  30.  *  in through the CPU interrupt lines, and ones that come in on
  31.  *  the via chip. The CPU mappings are:
  32.  *    0,1 - S/W (ignored)
  33.  *    2   - Galileo chip (timer)
  34.  *    3   - Tulip 0 + NCR SCSI
  35.  *    4   - Tulip 1
  36.  *    5   - 16550 UART
  37.  *    6   - VIA southbridge PIC
  38.  *    7   - unused
  39.  *
  40.  * The VIA chip is a master/slave 8259 setup and has the
  41.  *  following interrupts
  42.  *    8   - RTC
  43.  *    9   - PCI
  44.  *    14  - IDE0
  45.  *    15  - IDE1
  46.  *
  47.  * In the table we use a 1 to indicate that we use a VIA interrupt
  48.  *  line, and IE_IRQx to indicate that we use a CPU interrupt line
  49.  *
  50.  * We map all of these onto linux IRQ #s 0-15 and forget the rest
  51.  */
  52. #define NOINT_LINE 0
  53. #define CPUINT_LINE(x) IE_IRQ##x
  54. #define VIAINT_LINE 1
  55. #define COBALT_IRQS 16
  56. static unsigned short irqnr_to_type[COBALT_IRQS] =
  57. { CPUINT_LINE(0),  NOINT_LINE,      VIAINT_LINE,  NOINT_LINE,
  58.   CPUINT_LINE(1),  NOINT_LINE,      NOINT_LINE,   CPUINT_LINE(3),
  59.   VIAINT_LINE,     VIAINT_LINE,     NOINT_LINE,   NOINT_LINE,
  60.   NOINT_LINE,      CPUINT_LINE(2),  VIAINT_LINE,  VIAINT_LINE };
  61. /*
  62.  * Cobalt CPU irq
  63.  */
  64. static void enable_cpu_irq(unsigned int irq)
  65. {
  66. unsigned long flags;
  67. save_and_cli(flags);
  68. change_cp0_status(irqnr_to_type[irq], irqnr_to_type[irq]);
  69. restore_flags(flags);
  70. }
  71. static unsigned startup_cpu_irq(unsigned int irq)
  72. {
  73. enable_cpu_irq(irq);
  74. return 0;
  75. }
  76. static void disable_cpu_irq(unsigned int irq)
  77. {
  78. unsigned long flags;
  79. save_and_cli(flags);
  80. change_cp0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq]));
  81. restore_flags(flags);
  82. }
  83. #define shutdown_cpu_irq disable_cpu_irq
  84. #define mask_and_ack_cpu_irq disable_cpu_irq
  85. static void end_cpu_irq(unsigned int irq)
  86. {
  87. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  88. enable_cpu_irq(irq);
  89. }
  90. static struct hw_interrupt_type cobalt_cpu_irq_type = {
  91. "Cobalt CPU",
  92. startup_cpu_irq,
  93. shutdown_cpu_irq,
  94. enable_cpu_irq,
  95. disable_cpu_irq,
  96. mask_and_ack_cpu_irq,
  97. end_cpu_irq,
  98. NULL
  99. };
  100. void __init init_IRQ(void)
  101. {
  102. int i;
  103. /* Initialise all of the IRQ descriptors */
  104. init_i8259_irqs();
  105. /* Map the irqnr to the type int we have */
  106. for (i=0; i < COBALT_IRQS; i++) {
  107. if (irqnr_to_type[i] >= CPUINT_LINE(0))
  108. /* cobalt_cpu_irq_type */
  109. irq_desc[i].handler = &cobalt_cpu_irq_type;
  110. }
  111. /* Mask all cpu interrupts
  112.     (except IE4, we already masked those at VIA level) */
  113. clear_cp0_status(ST0_IM);
  114. set_cp0_status(IE_IRQ4);
  115. cli();
  116. set_except_vector(0, cobalt_handle_int);
  117. }