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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/mach-footbridge/irq.c
  3.  *
  4.  *  Copyright (C) 1996-2000 Russell King
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  *
  10.  *  Changelog:
  11.  *   22-Aug-1998 RMK Restructured IRQ routines
  12.  *   03-Sep-1998 PJB Merged CATS support
  13.  *   20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
  14.  *   26-Jan-1999 PJB Don't use IACK on CATS
  15.  *   16-Mar-1999 RMK Added autodetect of ISA PICs
  16.  */
  17. #include <linux/sched.h>
  18. #include <linux/ioport.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/init.h>
  21. #include <asm/mach/irq.h>
  22. #include <asm/hardware.h>
  23. #include <asm/hardware/dec21285.h>
  24. #include <asm/irq.h>
  25. #include <asm/io.h>
  26. #include <asm/mach-types.h>
  27. /*
  28.  * Footbridge IRQ translation table
  29.  *  Converts from our IRQ numbers into FootBridge masks
  30.  */
  31. static const int fb_irq_mask[] = {
  32. IRQ_MASK_UART_RX, /*  0 */
  33. IRQ_MASK_UART_TX, /*  1 */
  34. IRQ_MASK_TIMER1, /*  2 */
  35. IRQ_MASK_TIMER2, /*  3 */
  36. IRQ_MASK_TIMER3, /*  4 */
  37. IRQ_MASK_IN0, /*  5 */
  38. IRQ_MASK_IN1, /*  6 */
  39. IRQ_MASK_IN2, /*  7 */
  40. IRQ_MASK_IN3, /*  8 */
  41. IRQ_MASK_DOORBELLHOST, /*  9 */
  42. IRQ_MASK_DMA1, /* 10 */
  43. IRQ_MASK_DMA2, /* 11 */
  44. IRQ_MASK_PCI, /* 12 */
  45. IRQ_MASK_SDRAMPARITY, /* 13 */
  46. IRQ_MASK_I2OINPOST, /* 14 */
  47. IRQ_MASK_PCI_ABORT, /* 15 */
  48. IRQ_MASK_PCI_SERR, /* 16 */
  49. IRQ_MASK_DISCARD_TIMER, /* 17 */
  50. IRQ_MASK_PCI_DPERR, /* 18 */
  51. IRQ_MASK_PCI_PERR, /* 19 */
  52. };
  53. static void fb_mask_irq(unsigned int irq)
  54. {
  55. *CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
  56. }
  57. static void fb_unmask_irq(unsigned int irq)
  58. {
  59. *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
  60. }
  61. static void __init __fb_init_irq(void)
  62. {
  63. int irq;
  64. /*
  65.  * setup DC21285 IRQs
  66.  */
  67. *CSR_IRQ_DISABLE = -1;
  68. *CSR_FIQ_DISABLE = -1;
  69. for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
  70. irq_desc[irq].valid = 1;
  71. irq_desc[irq].probe_ok = 1;
  72. irq_desc[irq].mask_ack = fb_mask_irq;
  73. irq_desc[irq].mask = fb_mask_irq;
  74. irq_desc[irq].unmask = fb_unmask_irq;
  75. }
  76. }
  77. extern int isa_irq;
  78. static void isa_mask_pic_lo_irq(unsigned int irq)
  79. {
  80. unsigned int mask = 1 << (irq & 7);
  81. outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
  82. }
  83. static void isa_mask_ack_pic_lo_irq(unsigned int irq)
  84. {
  85. unsigned int mask = 1 << (irq & 7);
  86. outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
  87. outb(0x20, PIC_LO);
  88. }
  89. static void isa_unmask_pic_lo_irq(unsigned int irq)
  90. {
  91. unsigned int mask = 1 << (irq & 7);
  92. outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
  93. }
  94. static void isa_mask_pic_hi_irq(unsigned int irq)
  95. {
  96. unsigned int mask = 1 << (irq & 7);
  97. outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
  98. }
  99. static void isa_mask_ack_pic_hi_irq(unsigned int irq)
  100. {
  101. unsigned int mask = 1 << (irq & 7);
  102. outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
  103. outb(0x62, PIC_LO);
  104. outb(0x20, PIC_HI);
  105. }
  106. static void isa_unmask_pic_hi_irq(unsigned int irq)
  107. {
  108. unsigned int mask = 1 << (irq & 7);
  109. outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
  110. }
  111. static void no_action(int irq, void *dev_id, struct pt_regs *regs)
  112. {
  113. }
  114. static struct irqaction irq_cascade = { handler: no_action, name: "cascade", };
  115. static struct resource pic1_resource = { "pic1", 0x20, 0x3f };
  116. static struct resource pic2_resource = { "pic2", 0xa0, 0xbf };
  117. static void __init isa_init_irq(int irq)
  118. {
  119. /*
  120.  * Setup, and then probe for an ISA PIC
  121.  * If the PIC is not there, then we
  122.  * ignore the PIC.
  123.  */
  124. outb(0x11, PIC_LO);
  125. outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */
  126. outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */
  127. outb(0x01, PIC_MASK_LO); /* x86 */
  128. outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */
  129. outb(0x11, PIC_HI);
  130. outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */
  131. outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */
  132. outb(0x01, PIC_MASK_HI); /* x86 */
  133. outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */
  134. outb(0x0b, PIC_LO);
  135. outb(0x0b, PIC_HI);
  136. if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
  137. outb(0xff, PIC_MASK_LO);/* mask all IRQs */
  138. outb(0xff, PIC_MASK_HI);/* mask all IRQs */
  139. isa_irq = irq;
  140. } else
  141. isa_irq = -1;
  142. if (isa_irq != -1) {
  143. for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
  144. irq_desc[irq].valid = 1;
  145. irq_desc[irq].probe_ok = 1;
  146. irq_desc[irq].mask_ack = isa_mask_ack_pic_lo_irq;
  147. irq_desc[irq].mask = isa_mask_pic_lo_irq;
  148. irq_desc[irq].unmask = isa_unmask_pic_lo_irq;
  149. }
  150. for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
  151. irq_desc[irq].valid = 1;
  152. irq_desc[irq].probe_ok = 1;
  153. irq_desc[irq].mask_ack = isa_mask_ack_pic_hi_irq;
  154. irq_desc[irq].mask = isa_mask_pic_hi_irq;
  155. irq_desc[irq].unmask = isa_unmask_pic_hi_irq;
  156. }
  157. request_resource(&ioport_resource, &pic1_resource);
  158. request_resource(&ioport_resource, &pic2_resource);
  159. setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade);
  160. setup_arm_irq(isa_irq, &irq_cascade);
  161. /*
  162.  * On the NetWinder, don't automatically
  163.  * enable ISA IRQ11 when it is requested.
  164.  * There appears to be a missing pull-up
  165.  * resistor on this line.
  166.  */
  167. if (machine_is_netwinder())
  168. irq_desc[_ISA_IRQ(11)].noautoenable = 1;
  169. }
  170. }
  171. void __init footbridge_init_irq(void)
  172. {
  173. __fb_init_irq();
  174. if (!footbridge_cfn_mode())
  175. return;
  176. if (machine_is_ebsa285())
  177. /* The following is dependent on which slot
  178.  * you plug the Southbridge card into.  We
  179.  * currently assume that you plug it into
  180.  * the right-hand most slot.
  181.  */
  182. isa_init_irq(IRQ_PCI);
  183. if (machine_is_cats())
  184. isa_init_irq(IRQ_IN2);
  185. if (machine_is_netwinder())
  186. isa_init_irq(IRQ_IN3);
  187. }