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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2000 RidgeRun, Inc.
  3.  * Author: RidgeRun, Inc.
  4.  *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
  5.  *
  6.  * Copyright 2001 MontaVista Software Inc.
  7.  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  8.  * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
  9.  *
  10.  *  This program is free software; you can redistribute  it and/or modify it
  11.  *  under  the terms of  the GNU General  Public License as published by the
  12.  *  Free Software Foundation;  either version 2 of the  License, or (at your
  13.  *  option) any later version.
  14.  *
  15.  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  16.  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  17.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  18.  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  19.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20.  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  21.  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22.  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  23.  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24.  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  *
  26.  *  You should have received a copy of the  GNU General Public License along
  27.  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  28.  *  675 Mass Ave, Cambridge, MA 02139, USA.
  29.  *
  30.  */
  31. #include <linux/errno.h>
  32. #include <linux/init.h>
  33. #include <linux/kernel_stat.h>
  34. #include <linux/module.h>
  35. #include <linux/signal.h>
  36. #include <linux/sched.h>
  37. #include <linux/types.h>
  38. #include <linux/interrupt.h>
  39. #include <linux/ioport.h>
  40. #include <linux/timex.h>
  41. #include <linux/slab.h>
  42. #include <linux/random.h>
  43. #include <asm/bitops.h>
  44. #include <asm/bootinfo.h>
  45. #include <asm/io.h>
  46. #include <asm/irq.h>
  47. #include <asm/mipsregs.h>
  48. #include <asm/system.h>
  49. static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED;
  50. /* Function for careful CP0 interrupt mask access */
  51. static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
  52. {
  53. unsigned long status;
  54. unsigned clr_mask;
  55. unsigned set_mask;
  56. /* do the low 8 bits first */
  57. clr_mask = 0xff & clr_mask_in;
  58. set_mask = 0xff & set_mask_in;
  59. status = read_32bit_cp0_register(CP0_STATUS);
  60. status &= ~((clr_mask & 0xFF) << 8);
  61. status |= (set_mask & 0xFF) << 8;
  62. write_32bit_cp0_register(CP0_STATUS, status);
  63. /* do the high 8 bits */
  64. clr_mask = 0xff & (clr_mask_in >> 8);
  65. set_mask = 0xff & (set_mask_in >> 8);
  66. status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
  67. status &= ~((clr_mask & 0xFF) << 8);
  68. status |= (set_mask & 0xFF) << 8;
  69. write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
  70. }
  71. static inline void mask_irq(unsigned int irq)
  72. {
  73. modify_cp0_intmask(irq, 0);
  74. }
  75. static inline void unmask_irq(unsigned int irq)
  76. {
  77. modify_cp0_intmask(0, irq);
  78. }
  79. static void enable_cp7000_irq(unsigned int irq)
  80. {
  81. unsigned long flags;
  82. spin_lock_irqsave(&rm7000_irq_lock, flags);
  83. unmask_irq(1 << irq);
  84. spin_unlock_irqrestore(&rm7000_irq_lock, flags);
  85. }
  86. static unsigned int startup_cp7000_irq(unsigned int irq)
  87. {
  88. enable_cp7000_irq(irq);
  89. return 0; /* never anything pending */
  90. }
  91. static void disable_cp7000_irq(unsigned int irq)
  92. {
  93. unsigned long flags;
  94. spin_lock_irqsave(&rm7000_irq_lock, flags);
  95. mask_irq(1 << irq);
  96. spin_unlock_irqrestore(&rm7000_irq_lock, flags);
  97. }
  98. #define shutdown_cp7000_irq disable_cp7000_irq
  99. static void mask_and_ack_cp7000_irq(unsigned int irq)
  100. {
  101. mask_irq(1 << irq);
  102. }
  103. static void end_cp7000_irq(unsigned int irq)
  104. {
  105. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  106. unmask_irq(1 << irq);
  107. }
  108. static struct hw_interrupt_type cp7000_hpcdma_irq_type = {
  109. "CP7000",
  110. startup_cp7000_irq,
  111. shutdown_cp7000_irq,
  112. enable_cp7000_irq,
  113. disable_cp7000_irq,
  114. mask_and_ack_cp7000_irq,
  115. end_cp7000_irq,
  116. NULL
  117. };
  118. extern asmlinkage void ocelot_handle_int(void);
  119. extern void gt64240_irq_init(void);
  120. void __init init_IRQ(void)
  121. {
  122. int i;
  123. /*
  124.  * Clear all of the interrupts while we change the able around a bit.
  125.  * int-handler is not on bootstrap
  126.  */
  127. clear_cp0_status(ST0_IM | ST0_BEV);
  128. __cli();
  129. /* Sets the first-level interrupt dispatcher. */
  130. set_except_vector(0, ocelot_handle_int);
  131. init_generic_irq();
  132. for (i = 0; i <= 15; i++) {
  133. irq_desc[i].status = IRQ_DISABLED;
  134. irq_desc[i].action = 0;
  135. irq_desc[i].depth = 1;
  136. irq_desc[i].handler = &cp7000_hpcdma_irq_type;
  137. }
  138. gt64240_irq_init();
  139. #ifdef CONFIG_REMOTE_DEBUG
  140. printk("start kgdb ...n");
  141. set_debug_traps();
  142. breakpoint(); /* you may move this line to whereever you want :-) */
  143. #endif
  144. #ifdef CONFIG_GDB_CONSOLE
  145. register_gdb_console();
  146. #endif
  147. }