i8259.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * i8259 interrupt controller driver.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/init.h>
  10. #include <linux/ioport.h>
  11. #include <linux/interrupt.h>
  12. #include <asm/io.h>
  13. #include <asm/i8259.h>
  14. static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
  15. static unsigned char cached_8259[2] = { 0xff, 0xff };
  16. #define cached_A1 (cached_8259[0])
  17. #define cached_21 (cached_8259[1])
  18. static DEFINE_SPINLOCK(i8259_lock);
  19. static int i8259_pic_irq_offset;
  20. /*
  21. * Acknowledge the IRQ using either the PCI host bridge's interrupt
  22. * acknowledge feature or poll. How i8259_init() is called determines
  23. * which is called. It should be noted that polling is broken on some
  24. * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
  25. */
  26. int i8259_irq(struct pt_regs *regs)
  27. {
  28. int irq;
  29. spin_lock(&i8259_lock);
  30. /* Either int-ack or poll for the IRQ */
  31. if (pci_intack)
  32. irq = readb(pci_intack);
  33. else {
  34. /* Perform an interrupt acknowledge cycle on controller 1. */
  35. outb(0x0C, 0x20); /* prepare for poll */
  36. irq = inb(0x20) & 7;
  37. if (irq == 2 ) {
  38. /*
  39. * Interrupt is cascaded so perform interrupt
  40. * acknowledge on controller 2.
  41. */
  42. outb(0x0C, 0xA0); /* prepare for poll */
  43. irq = (inb(0xA0) & 7) + 8;
  44. }
  45. }
  46. if (irq == 7) {
  47. /*
  48. * This may be a spurious interrupt.
  49. *
  50. * Read the interrupt status register (ISR). If the most
  51. * significant bit is not set then there is no valid
  52. * interrupt.
  53. */
  54. if (!pci_intack)
  55. outb(0x0B, 0x20); /* ISR register */
  56. if(~inb(0x20) & 0x80)
  57. irq = -1;
  58. }
  59. spin_unlock(&i8259_lock);
  60. return irq + i8259_pic_irq_offset;
  61. }
  62. int i8259_irq_cascade(struct pt_regs *regs, void *unused)
  63. {
  64. return i8259_irq(regs);
  65. }
  66. static void i8259_mask_and_ack_irq(unsigned int irq_nr)
  67. {
  68. unsigned long flags;
  69. spin_lock_irqsave(&i8259_lock, flags);
  70. irq_nr -= i8259_pic_irq_offset;
  71. if (irq_nr > 7) {
  72. cached_A1 |= 1 << (irq_nr-8);
  73. inb(0xA1); /* DUMMY */
  74. outb(cached_A1, 0xA1);
  75. outb(0x20, 0xA0); /* Non-specific EOI */
  76. outb(0x20, 0x20); /* Non-specific EOI to cascade */
  77. } else {
  78. cached_21 |= 1 << irq_nr;
  79. inb(0x21); /* DUMMY */
  80. outb(cached_21, 0x21);
  81. outb(0x20, 0x20); /* Non-specific EOI */
  82. }
  83. spin_unlock_irqrestore(&i8259_lock, flags);
  84. }
  85. static void i8259_set_irq_mask(int irq_nr)
  86. {
  87. outb(cached_A1,0xA1);
  88. outb(cached_21,0x21);
  89. }
  90. static void i8259_mask_irq(unsigned int irq_nr)
  91. {
  92. unsigned long flags;
  93. spin_lock_irqsave(&i8259_lock, flags);
  94. irq_nr -= i8259_pic_irq_offset;
  95. if (irq_nr < 8)
  96. cached_21 |= 1 << irq_nr;
  97. else
  98. cached_A1 |= 1 << (irq_nr-8);
  99. i8259_set_irq_mask(irq_nr);
  100. spin_unlock_irqrestore(&i8259_lock, flags);
  101. }
  102. static void i8259_unmask_irq(unsigned int irq_nr)
  103. {
  104. unsigned long flags;
  105. spin_lock_irqsave(&i8259_lock, flags);
  106. irq_nr -= i8259_pic_irq_offset;
  107. if (irq_nr < 8)
  108. cached_21 &= ~(1 << irq_nr);
  109. else
  110. cached_A1 &= ~(1 << (irq_nr-8));
  111. i8259_set_irq_mask(irq_nr);
  112. spin_unlock_irqrestore(&i8259_lock, flags);
  113. }
  114. static void i8259_end_irq(unsigned int irq)
  115. {
  116. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
  117. && irq_desc[irq].action)
  118. i8259_unmask_irq(irq);
  119. }
  120. struct hw_interrupt_type i8259_pic = {
  121. .typename = " i8259 ",
  122. .enable = i8259_unmask_irq,
  123. .disable = i8259_mask_irq,
  124. .ack = i8259_mask_and_ack_irq,
  125. .end = i8259_end_irq,
  126. };
  127. static struct resource pic1_iores = {
  128. .name = "8259 (master)",
  129. .start = 0x20,
  130. .end = 0x21,
  131. .flags = IORESOURCE_BUSY,
  132. };
  133. static struct resource pic2_iores = {
  134. .name = "8259 (slave)",
  135. .start = 0xa0,
  136. .end = 0xa1,
  137. .flags = IORESOURCE_BUSY,
  138. };
  139. static struct resource pic_edgectrl_iores = {
  140. .name = "8259 edge control",
  141. .start = 0x4d0,
  142. .end = 0x4d1,
  143. .flags = IORESOURCE_BUSY,
  144. };
  145. static struct irqaction i8259_irqaction = {
  146. .handler = no_action,
  147. .flags = SA_INTERRUPT,
  148. .mask = CPU_MASK_NONE,
  149. .name = "82c59 secondary cascade",
  150. };
  151. /*
  152. * i8259_init()
  153. * intack_addr - PCI interrupt acknowledge (real) address which will return
  154. * the active irq from the 8259
  155. */
  156. void __init i8259_init(unsigned long intack_addr, int offset)
  157. {
  158. unsigned long flags;
  159. int i;
  160. spin_lock_irqsave(&i8259_lock, flags);
  161. i8259_pic_irq_offset = offset;
  162. /* init master interrupt controller */
  163. outb(0x11, 0x20); /* Start init sequence */
  164. outb(0x00, 0x21); /* Vector base */
  165. outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
  166. outb(0x01, 0x21); /* Select 8086 mode */
  167. /* init slave interrupt controller */
  168. outb(0x11, 0xA0); /* Start init sequence */
  169. outb(0x08, 0xA1); /* Vector base */
  170. outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
  171. outb(0x01, 0xA1); /* Select 8086 mode */
  172. /* always read ISR */
  173. outb(0x0B, 0x20);
  174. outb(0x0B, 0xA0);
  175. /* Mask all interrupts */
  176. outb(cached_A1, 0xA1);
  177. outb(cached_21, 0x21);
  178. spin_unlock_irqrestore(&i8259_lock, flags);
  179. for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
  180. irq_desc[offset + i].handler = &i8259_pic;
  181. /* reserve our resources */
  182. setup_irq(offset + 2, &i8259_irqaction);
  183. request_resource(&ioport_resource, &pic1_iores);
  184. request_resource(&ioport_resource, &pic2_iores);
  185. request_resource(&ioport_resource, &pic_edgectrl_iores);
  186. if (intack_addr != 0)
  187. pci_intack = ioremap(intack_addr, 1);
  188. }