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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright 2001 MontaVista Software Inc.
  3.  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  4.  *
  5.  * Copyright (C) 2001 Ralf Baechle
  6.  *
  7.  * This file define the irq handler for MIPS CPU interrupts.
  8.  *
  9.  * This program is free software; you can redistribute  it and/or modify it
  10.  * under  the terms of  the GNU General  Public License as published by the
  11.  * Free Software Foundation;  either version 2 of the  License, or (at your
  12.  * option) any later version.
  13.  */
  14. /*
  15.  * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
  16.  * level triggered (i.e., cannot be cleared from CPU; must be cleared from
  17.  * device).  The first two are software interrupts which we don't really
  18.  * use or support.  The last one is usually cpu timer interrupt if a counter
  19.  * register is present.
  20.  *
  21.  * Don't even think about using this on SMP.  You have been warned.
  22.  *
  23.  * This file exports one global function:
  24.  * mips_cpu_irq_init(u32 irq_base);
  25.  */
  26. #include <linux/interrupt.h>
  27. #include <linux/types.h>
  28. #include <linux/kernel.h>
  29. #include <asm/mipsregs.h>
  30. #include <asm/system.h>
  31. static int mips_cpu_irq_base;
  32. static inline void unmask_mips_irq(unsigned int irq)
  33. {
  34. clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base));
  35. set_cp0_status(0x100 << (irq - mips_cpu_irq_base));
  36. }
  37. static inline void mask_mips_irq(unsigned int irq)
  38. {
  39. clear_cp0_status(0x100 << (irq - mips_cpu_irq_base));
  40. }
  41. static inline void mips_cpu_irq_enable(unsigned int irq)
  42. {
  43. unsigned long flags;
  44. local_irq_save(flags);
  45. unmask_mips_irq(irq);
  46. local_irq_restore(flags);
  47. }
  48. static void mips_cpu_irq_disable(unsigned int irq)
  49. {
  50. unsigned long flags;
  51. local_irq_save(flags);
  52. mask_mips_irq(irq);
  53. local_irq_restore(flags);
  54. }
  55. static unsigned int mips_cpu_irq_startup(unsigned int irq)
  56. {
  57. mips_cpu_irq_enable(irq);
  58. return 0;
  59. }
  60. #define mips_cpu_irq_shutdown mips_cpu_irq_disable
  61. /*
  62.  * While we ack the interrupt interrupts are disabled and thus we don't need
  63.  * to deal with concurrency issues.  Same for mips_cpu_irq_end.
  64.  */
  65. static void mips_cpu_irq_ack(unsigned int irq)
  66. {
  67. /* Only necessary for soft interrupts */
  68. clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8));
  69. mask_mips_irq(irq);
  70. }
  71. static void mips_cpu_irq_end(unsigned int irq)
  72. {
  73. if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
  74. unmask_mips_irq(irq);
  75. }
  76. static hw_irq_controller mips_cpu_irq_controller = {
  77. "CPU_irq",
  78. mips_cpu_irq_startup,
  79. mips_cpu_irq_shutdown,
  80. mips_cpu_irq_enable,
  81. mips_cpu_irq_disable,
  82. mips_cpu_irq_ack,
  83. mips_cpu_irq_end,
  84. NULL /* no affinity stuff for UP */
  85. };
  86. void mips_cpu_irq_init(u32 irq_base)
  87. {
  88. u32 i;
  89. for (i = irq_base; i < irq_base + 8; i++) {
  90. irq_desc[i].status = IRQ_DISABLED;
  91. irq_desc[i].action = NULL;
  92. irq_desc[i].depth = 1;
  93. irq_desc[i].handler = &mips_cpu_irq_controller;
  94. }
  95. mips_cpu_irq_base = irq_base;
  96. }