irq_intc2.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/sh/kernel/irq_intc2.c
  3.  *
  4.  * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
  5.  *
  6.  * May be copied or modified under the terms of the GNU General Public
  7.  * License.  See linux/COPYING for more information.                            
  8.  *
  9.  * Interrupt handling for INTC2-based IRQ.
  10.  *
  11.  * These are the "new Hitachi style" interrupts, as present on the 
  12.  * Hitachi 7751 and the STM ST40 STB1.
  13.  */
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/irq.h>
  17. #include <asm/system.h>
  18. #include <asm/io.h>
  19. #include <asm/machvec.h>
  20. struct intc2_data {
  21. unsigned int addr; /* Address of Interrupt Priority Register */
  22. int mask; /*Mask to apply */
  23. };
  24. static struct intc2_data intc2_data[NR_INTC2_IRQS];
  25. static void enable_intc2_irq(unsigned int irq);
  26. static void disable_intc2_irq(unsigned int irq);
  27. /* shutdown is same as "disable" */
  28. #define shutdown_intc2_irq disable_intc2_irq
  29. static void mask_and_ack_intc2(unsigned int);
  30. static void end_intc2_irq(unsigned int irq);
  31. static unsigned int startup_intc2_irq(unsigned int irq)
  32. enable_intc2_irq(irq);
  33. return 0; /* never anything pending */
  34. }
  35. static struct hw_interrupt_type intc2_irq_type = {
  36. "INTC2-IRQ",
  37. startup_intc2_irq,
  38. shutdown_intc2_irq,
  39. enable_intc2_irq,
  40. disable_intc2_irq,
  41. mask_and_ack_intc2,
  42. end_intc2_irq
  43. };
  44. static void disable_intc2_irq(unsigned int irq)
  45. {
  46. unsigned addr;
  47. int offset=irq-INTC2_FIRST_IRQ;
  48. unsigned val,flags;
  49. // Sanity check
  50. if(offset<0 || offset>=NR_INTC2_IRQS) return;
  51. addr=intc2_data[offset].addr+INTC2_INTMSK_OFFSET;
  52. save_and_cli(flags);
  53. val=ctrl_inl(addr);
  54. val|=intc2_data[offset].mask;
  55. ctrl_outl(val,addr);
  56. restore_flags(flags);
  57. }
  58. static void enable_intc2_irq(unsigned int irq)
  59. {
  60. int offset=irq-INTC2_FIRST_IRQ;
  61. // Sanity check
  62. if(offset<0 || offset>=NR_INTC2_IRQS) return;
  63. ctrl_outl(intc2_data[offset].mask,
  64.   intc2_data[offset].addr+INTC2_INTMSKCLR_OFFSET);
  65. }
  66. static void mask_and_ack_intc2(unsigned int irq)
  67. {
  68. disable_intc2_irq(irq);
  69. }
  70. static void end_intc2_irq(unsigned int irq)
  71. {
  72. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  73. enable_intc2_irq(irq);
  74. }
  75. void make_intc2_irq(unsigned int irq, unsigned int addr, 
  76.     unsigned int group,int pos, int priority)
  77. {
  78. int offset=irq-INTC2_FIRST_IRQ;
  79. unsigned flags,val;
  80. if(offset<0 || offset>=NR_INTC2_IRQS) {
  81. return;
  82. }
  83. disable_irq_nosync(irq);
  84. /* Fill the the data we need */
  85. intc2_data[offset].addr=addr;
  86. intc2_data[offset].mask=1<<pos;
  87. /* Set the priority level */
  88. save_and_cli(flags);
  89. val=ctrl_inl(addr+INTC2_INTPRI_OFFSET);
  90. val|=(priority)<< (group<<4);
  91. ctrl_outl(val,addr+INTC2_INTPRI_OFFSET);
  92. restore_flags(flags);
  93. irq_desc[irq].handler=&intc2_irq_type;
  94. disable_intc2_irq(irq);
  95. }