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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
  3.  *
  4.  * May be copied or modified under the terms of the GNU General Public
  5.  * License.  See linux/COPYING for more information.                            
  6.  *
  7.  * Looks after interrupts on the HARP board.
  8.  *
  9.  * Bases on the IPR irq system
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/init.h>
  13. #include <linux/irq.h>
  14. #include <asm/system.h>
  15. #include <asm/io.h>
  16. #include "harp.h"
  17. #define NUM_EXTERNAL_IRQS 16
  18. // Early versions of the STB1 Overdrive required this nasty frig
  19. //#define INVERT_INTMASK_WRITES
  20. static void enable_harp_irq(unsigned int irq);
  21. static void disable_harp_irq(unsigned int irq);
  22. /* shutdown is same as "disable" */
  23. #define shutdown_harp_irq disable_harp_irq
  24. static void mask_and_ack_harp(unsigned int);
  25. static void end_harp_irq(unsigned int irq);
  26. static unsigned int startup_harp_irq(unsigned int irq)
  27. {
  28. enable_harp_irq(irq);
  29. return 0; /* never anything pending */
  30. }
  31. static struct hw_interrupt_type harp_irq_type = {
  32. "Harp-IRQ",
  33. startup_harp_irq,
  34. shutdown_harp_irq,
  35. enable_harp_irq,
  36. disable_harp_irq,
  37. mask_and_ack_harp,
  38. end_harp_irq
  39. };
  40. static void disable_harp_irq(unsigned int irq)
  41. {
  42. unsigned val, flags;
  43. unsigned maskReg;
  44. unsigned mask;
  45. int pri;
  46. if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
  47. return;
  48. pri = 15 - irq;
  49. if (pri < 8) {
  50. maskReg = EPLD_INTMASK0;
  51. } else {
  52. maskReg = EPLD_INTMASK1;
  53. pri -= 8;
  54. }
  55. save_and_cli(flags);
  56. mask = ctrl_inl(maskReg);
  57. mask &= (~(1 << pri));
  58. #if defined(INVERT_INTMASK_WRITES)
  59. mask ^= 0xff;
  60. #endif
  61. ctrl_outl(mask, maskReg);
  62. restore_flags(flags);
  63. }
  64. static void enable_harp_irq(unsigned int irq)
  65. {
  66. unsigned flags;
  67. unsigned maskReg;
  68. unsigned mask;
  69. int pri;
  70. if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
  71. return;
  72. pri = 15 - irq;
  73. if (pri < 8) {
  74. maskReg = EPLD_INTMASK0;
  75. } else {
  76. maskReg = EPLD_INTMASK1;
  77. pri -= 8;
  78. }
  79. save_and_cli(flags);
  80. mask = ctrl_inl(maskReg);
  81. mask |= (1 << pri);
  82. #if defined(INVERT_INTMASK_WRITES)
  83. mask ^= 0xff;
  84. #endif
  85. ctrl_outl(mask, maskReg);
  86. restore_flags(flags);
  87. }
  88. /* This functions sets the desired irq handler to be an overdrive type */
  89. static void __init make_harp_irq(unsigned int irq)
  90. {
  91. disable_irq_nosync(irq);
  92. irq_desc[irq].handler = &harp_irq_type;
  93. disable_harp_irq(irq);
  94. }
  95. static void mask_and_ack_harp(unsigned int irq)
  96. {
  97. disable_harp_irq(irq);
  98. }
  99. static void end_harp_irq(unsigned int irq)
  100. {
  101. enable_harp_irq(irq);
  102. }
  103. void __init init_harp_irq(void)
  104. {
  105. int i;
  106. #if !defined(INVERT_INTMASK_WRITES)
  107. // On the harp these are set to enable an interrupt
  108. ctrl_outl(0x00, EPLD_INTMASK0);
  109. ctrl_outl(0x00, EPLD_INTMASK1);
  110. #else
  111. // On the Overdrive the data is inverted before being stored in the reg
  112. ctrl_outl(0xff, EPLD_INTMASK0);
  113. ctrl_outl(0xff, EPLD_INTMASK1);
  114. #endif
  115. for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
  116. make_harp_irq(i);
  117. }
  118. }