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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.ppc8260_pic.c 1.5 05/17/01 18:14:21 cort
  3.  */
  4. #include <linux/stddef.h>
  5. #include <linux/init.h>
  6. #include <linux/sched.h>
  7. #include <linux/signal.h>
  8. #include <asm/irq.h>
  9. #include <asm/immap_8260.h>
  10. #include <asm/mpc8260.h>
  11. #include "ppc8260_pic.h"
  12. /* The 8260 internal interrupt controller.  It is usually
  13.  * the only interrupt controller.
  14.  * There are two 32-bit registers (high/low) for up to 64
  15.  * possible interrupts.
  16.  *
  17.  * Now, the fun starts.....Interrupt Numbers DO NOT MAP
  18.  * in a simple arithmetic fashion to mask or pending registers.
  19.  * That is, interrupt 4 does not map to bit position 4.
  20.  * We create two tables, indexed by vector number, to indicate
  21.  * which register to use and which bit in the register to use.
  22.  */
  23. static u_char irq_to_siureg[] = {
  24. 1, 1, 1, 1, 1, 1, 1, 1,
  25. 1, 1, 1, 1, 1, 1, 1, 1,
  26. 0, 0, 0, 0, 0, 0, 0, 0,
  27. 0, 0, 0, 0, 0, 0, 0, 0,
  28. 1, 1, 1, 1, 1, 1, 1, 1,
  29. 1, 1, 1, 1, 1, 1, 1, 1,
  30. 0, 0, 0, 0, 0, 0, 0, 0,
  31. 0, 0, 0, 0, 0, 0, 0, 0
  32. };
  33. static u_char irq_to_siubit[] = {
  34. 31, 16, 17, 18, 19, 20, 21, 22,
  35. 23, 24, 25, 26, 27, 28, 29, 30,
  36. 29, 30, 16, 17, 18, 19, 20, 21,
  37. 22, 23, 24, 25, 26, 27, 28, 31,
  38.  0,  1,  2,  3,  4,  5,  6,  7,
  39.  8,  9, 10, 11, 12, 13, 14, 15,
  40. 15, 14, 13, 12, 11, 10,  9,  8,
  41.  7,  6,  5,  4,  3,  2,  1,  0
  42. };
  43. static void m8260_mask_irq(unsigned int irq_nr)
  44. {
  45. int bit, word;
  46. volatile uint *simr;
  47. bit = irq_to_siubit[irq_nr];
  48. word = irq_to_siureg[irq_nr];
  49. simr = &(immr->im_intctl.ic_simrh);
  50. ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
  51. simr[word] = ppc_cached_irq_mask[word];
  52. }
  53. static void m8260_unmask_irq(unsigned int irq_nr)
  54. {
  55. int bit, word;
  56. volatile uint *simr;
  57. bit = irq_to_siubit[irq_nr];
  58. word = irq_to_siureg[irq_nr];
  59. simr = &(immr->im_intctl.ic_simrh);
  60. ppc_cached_irq_mask[word] |= (1 << (31 - bit));
  61. simr[word] = ppc_cached_irq_mask[word];
  62. }
  63. static void m8260_mask_and_ack(unsigned int irq_nr)
  64. {
  65. int bit, word;
  66. volatile uint *simr, *sipnr;
  67. bit = irq_to_siubit[irq_nr];
  68. word = irq_to_siureg[irq_nr];
  69. simr = &(immr->im_intctl.ic_simrh);
  70. sipnr = &(immr->im_intctl.ic_sipnrh);
  71. ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
  72. simr[word] = ppc_cached_irq_mask[word];
  73. sipnr[word] = 1 << (31 - bit);
  74. }
  75. static void m8260_end_irq(unsigned int irq_nr)
  76. {
  77. int bit, word;
  78. volatile uint *simr;
  79. if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
  80. bit = irq_to_siubit[irq_nr];
  81. word = irq_to_siureg[irq_nr];
  82. simr = &(immr->im_intctl.ic_simrh);
  83. ppc_cached_irq_mask[word] |= (1 << (31 - bit));
  84. simr[word] = ppc_cached_irq_mask[word];
  85. }
  86. }
  87. struct hw_interrupt_type ppc8260_pic = {
  88. " 8260 SIU  ",
  89. NULL,
  90. NULL,
  91. m8260_unmask_irq,
  92. m8260_mask_irq,
  93. m8260_mask_and_ack,
  94. m8260_end_irq,
  95. 0
  96. };
  97. int
  98. m8260_get_irq(struct pt_regs *regs)
  99. {
  100. int irq;
  101.         unsigned long bits;
  102.         /* For MPC8260, read the SIVEC register and shift the bits down
  103.          * to get the irq number.         */
  104.         bits = immr->im_intctl.ic_sivec;
  105.         irq = bits >> 26;
  106. if (irq == 0)
  107. return(-1);
  108. #if 0
  109.         irq += ppc8260_pic.irq_offset;
  110. #endif
  111. return irq;
  112. }