irq.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines
  3. *
  4. * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  5. * Sony Software Development Center Europe (SDCE), Brussels
  6. */
  7. #include <linux/init.h>
  8. #include <linux/irq.h>
  9. #include <linux/signal.h>
  10. #include <linux/sched.h>
  11. #include <linux/types.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/ioport.h>
  14. #include <asm/i8259.h>
  15. #include <asm/io.h>
  16. #include <asm/irq_cpu.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/nile4.h>
  19. #include <asm/ddb5xxx/ddb5xxx.h>
  20. #include <asm/ddb5xxx/ddb5074.h>
  21. static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
  22. #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
  23. #define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */
  24. #define M1543_PNP_DATA 0x03f1 /* PnP Data Port */
  25. #define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */
  26. #define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */
  27. #define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */
  28. #define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */
  29. #define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */
  30. #define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */
  31. #define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */
  32. #define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */
  33. #define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */
  34. static void m1543_irq_setup(void)
  35. {
  36. /*
  37. * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all
  38. * the possible IO sources in the M1543 are in use by us. We will
  39. * use the following mapping:
  40. *
  41. * IRQ1 - keyboard (default set by M1543)
  42. * IRQ3 - reserved for UART B (default set by M1543) (note that
  43. * the schematics for the DDB Vrc-5074 board seem to
  44. * indicate that IRQ3 is connected to the DS1386
  45. * watchdog timer interrupt output so we might have
  46. * a conflict)
  47. * IRQ4 - reserved for UART A (default set by M1543)
  48. * IRQ5 - parallel (default set by M1543)
  49. * IRQ8 - DS1386 time of day (RTC) interrupt
  50. * IRQ12 - mouse
  51. */
  52. /*
  53. * Assing mouse interrupt to IRQ12
  54. */
  55. /* Enter configuration mode */
  56. outb(0x51, M1543_PNP_CONFIG);
  57. outb(0x23, M1543_PNP_CONFIG);
  58. /* Select logical device 7 (Keyboard) */
  59. outb(0x07, M1543_PNP_INDEX);
  60. outb(0x07, M1543_PNP_DATA);
  61. /* Select IRQ12 */
  62. outb(0x72, M1543_PNP_INDEX);
  63. outb(0x0c, M1543_PNP_DATA);
  64. outb(0x30, M1543_PNP_INDEX);
  65. printk("device 7, 0x30: %02x\n",inb(M1543_PNP_DATA));
  66. outb(0x70, M1543_PNP_INDEX);
  67. printk("device 7, 0x70: %02x\n",inb(M1543_PNP_DATA));
  68. /* Leave configration mode */
  69. outb(0xbb, M1543_PNP_CONFIG);
  70. }
  71. static void ddb_local0_irqdispatch(struct pt_regs *regs)
  72. {
  73. u32 mask;
  74. int nile4_irq;
  75. mask = nile4_get_irq_stat(0);
  76. /* Handle the timer interrupt first */
  77. #if 0
  78. if (mask & (1 << NILE4_INT_GPT)) {
  79. do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
  80. mask &= ~(1 << NILE4_INT_GPT);
  81. }
  82. #endif
  83. for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
  84. if (mask & 1) {
  85. if (nile4_irq == NILE4_INT_INTE) {
  86. int i8259_irq;
  87. nile4_clear_irq(NILE4_INT_INTE);
  88. i8259_irq = nile4_i8259_iack();
  89. do_IRQ(i8259_irq, regs);
  90. } else
  91. do_IRQ(nile4_to_irq(nile4_irq), regs);
  92. }
  93. }
  94. static void ddb_local1_irqdispatch(void)
  95. {
  96. printk("ddb_local1_irqdispatch called\n");
  97. }
  98. static void ddb_buserror_irq(void)
  99. {
  100. printk("ddb_buserror_irq called\n");
  101. }
  102. static void ddb_8254timer_irq(void)
  103. {
  104. printk("ddb_8254timer_irq called\n");
  105. }
  106. asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
  107. {
  108. unsigned int pending = read_c0_cause() & read_c0_status();
  109. if (pending & CAUSEF_IP2)
  110. ddb_local0_irqdispatch(regs);
  111. else if (pending & CAUSEF_IP3)
  112. ddb_local1_irqdispatch();
  113. else if (pending & CAUSEF_IP6)
  114. ddb_buserror_irq();
  115. else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
  116. ddb_8254timer_irq();
  117. }
  118. void __init arch_init_irq(void)
  119. {
  120. /* setup cascade interrupts */
  121. setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade);
  122. setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
  123. nile4_irq_setup(NILE4_IRQ_BASE);
  124. m1543_irq_setup();
  125. init_i8259_irqs();
  126. printk("CPU_IRQ_BASE: %d\n",CPU_IRQ_BASE);
  127. mips_cpu_irq_init(CPU_IRQ_BASE);
  128. printk("enabling 8259 cascade\n");
  129. ddb5074_led_hex(0);
  130. /* Enable the interrupt cascade */
  131. nile4_enable_irq(NILE4_IRQ_BASE+IRQ_I8259_CASCADE);
  132. }