malta_int.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Carsten Langgaard, carstenl@mips.com
  3. * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
  4. * Copyright (C) 2001 Ralf Baechle
  5. *
  6. * This program is free software; you can distribute it and/or modify it
  7. * under the terms of the GNU General Public License (Version 2) as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  18. *
  19. * Routines for generic manipulation of the interrupts found on the MIPS
  20. * Malta board.
  21. * The interrupt controller is located in the South Bridge a PIIX4 device
  22. * with two internal 82C95 interrupt controllers.
  23. */
  24. #include <linux/init.h>
  25. #include <linux/irq.h>
  26. #include <linux/sched.h>
  27. #include <linux/slab.h>
  28. #include <linux/interrupt.h>
  29. #include <linux/kernel_stat.h>
  30. #include <linux/random.h>
  31. #include <asm/i8259.h>
  32. #include <asm/io.h>
  33. #include <asm/mips-boards/malta.h>
  34. #include <asm/mips-boards/maltaint.h>
  35. #include <asm/mips-boards/piix4.h>
  36. #include <asm/gt64120.h>
  37. #include <asm/mips-boards/generic.h>
  38. #include <asm/mips-boards/msc01_pci.h>
  39. extern asmlinkage void mipsIRQ(void);
  40. static DEFINE_SPINLOCK(mips_irq_lock);
  41. static inline int mips_pcibios_iack(void)
  42. {
  43. int irq;
  44. u32 dummy;
  45. /*
  46. * Determine highest priority pending interrupt by performing
  47. * a PCI Interrupt Acknowledge cycle.
  48. */
  49. switch(mips_revision_corid) {
  50. case MIPS_REVISION_CORID_CORE_MSC:
  51. case MIPS_REVISION_CORID_CORE_FPGA2:
  52. case MIPS_REVISION_CORID_CORE_EMUL_MSC:
  53. MSC_READ(MSC01_PCI_IACK, irq);
  54. irq &= 0xff;
  55. break;
  56. case MIPS_REVISION_CORID_QED_RM5261:
  57. case MIPS_REVISION_CORID_CORE_LV:
  58. case MIPS_REVISION_CORID_CORE_FPGA:
  59. case MIPS_REVISION_CORID_CORE_FPGAR2:
  60. irq = GT_READ(GT_PCI0_IACK_OFS);
  61. irq &= 0xff;
  62. break;
  63. case MIPS_REVISION_CORID_BONITO64:
  64. case MIPS_REVISION_CORID_CORE_20K:
  65. case MIPS_REVISION_CORID_CORE_EMUL_BON:
  66. /* The following will generate a PCI IACK cycle on the
  67. * Bonito controller. It's a little bit kludgy, but it
  68. * was the easiest way to implement it in hardware at
  69. * the given time.
  70. */
  71. BONITO_PCIMAP_CFG = 0x20000;
  72. /* Flush Bonito register block */
  73. dummy = BONITO_PCIMAP_CFG;
  74. iob(); /* sync */
  75. irq = *(volatile u32 *)(_pcictrl_bonito_pcicfg);
  76. iob(); /* sync */
  77. irq &= 0xff;
  78. BONITO_PCIMAP_CFG = 0;
  79. break;
  80. default:
  81. printk("Unknown Core card, don't know the system controller.\n");
  82. return -1;
  83. }
  84. return irq;
  85. }
  86. static inline int get_int(int *irq)
  87. {
  88. unsigned long flags;
  89. spin_lock_irqsave(&mips_irq_lock, flags);
  90. *irq = mips_pcibios_iack();
  91. /*
  92. * IRQ7 is used to detect spurious interrupts.
  93. * The interrupt acknowledge cycle returns IRQ7, if no
  94. * interrupts is requested.
  95. * We can differentiate between this situation and a
  96. * "Normal" IRQ7 by reading the ISR.
  97. */
  98. if (*irq == 7)
  99. {
  100. outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
  101. PIIX4_ICTLR1_OCW3);
  102. if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
  103. spin_unlock_irqrestore(&mips_irq_lock, flags);
  104. printk("We got a spurious interrupt from PIIX4.\n");
  105. atomic_inc(&irq_err_count);
  106. return -1; /* Spurious interrupt. */
  107. }
  108. }
  109. spin_unlock_irqrestore(&mips_irq_lock, flags);
  110. return 0;
  111. }
  112. void malta_hw0_irqdispatch(struct pt_regs *regs)
  113. {
  114. int irq;
  115. if (get_int(&irq))
  116. return; /* interrupt has already been cleared */
  117. do_IRQ(irq, regs);
  118. }
  119. void corehi_irqdispatch(struct pt_regs *regs)
  120. {
  121. unsigned int data,datahi;
  122. /* Mask out corehi interrupt. */
  123. clear_c0_status(IE_IRQ3);
  124. printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
  125. printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
  126. , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
  127. switch(mips_revision_corid) {
  128. case MIPS_REVISION_CORID_CORE_MSC:
  129. case MIPS_REVISION_CORID_CORE_FPGA2:
  130. case MIPS_REVISION_CORID_CORE_EMUL_MSC:
  131. break;
  132. case MIPS_REVISION_CORID_QED_RM5261:
  133. case MIPS_REVISION_CORID_CORE_LV:
  134. case MIPS_REVISION_CORID_CORE_FPGA:
  135. case MIPS_REVISION_CORID_CORE_FPGAR2:
  136. data = GT_READ(GT_INTRCAUSE_OFS);
  137. printk("GT_INTRCAUSE = %08x\n", data);
  138. data = GT_READ(GT_CPUERR_ADDRLO_OFS);
  139. datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
  140. printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
  141. break;
  142. case MIPS_REVISION_CORID_BONITO64:
  143. case MIPS_REVISION_CORID_CORE_20K:
  144. case MIPS_REVISION_CORID_CORE_EMUL_BON:
  145. data = BONITO_INTISR;
  146. printk("BONITO_INTISR = %08x\n", data);
  147. data = BONITO_INTEN;
  148. printk("BONITO_INTEN = %08x\n", data);
  149. data = BONITO_INTPOL;
  150. printk("BONITO_INTPOL = %08x\n", data);
  151. data = BONITO_INTEDGE;
  152. printk("BONITO_INTEDGE = %08x\n", data);
  153. data = BONITO_INTSTEER;
  154. printk("BONITO_INTSTEER = %08x\n", data);
  155. data = BONITO_PCICMD;
  156. printk("BONITO_PCICMD = %08x\n", data);
  157. break;
  158. }
  159. /* We die here*/
  160. die("CoreHi interrupt", regs);
  161. }
  162. void __init arch_init_irq(void)
  163. {
  164. set_except_vector(0, mipsIRQ);
  165. init_i8259_irqs();
  166. }