atlas_int.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Carsten Langgaard, carstenl@mips.com
  3. * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
  4. *
  5. * ########################################################################
  6. *
  7. * This program is free software; you can distribute it and/or modify it
  8. * under the terms of the GNU General Public License (Version 2) as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  19. *
  20. * ########################################################################
  21. *
  22. * Routines for generic manipulation of the interrupts found on the MIPS
  23. * Atlas board.
  24. *
  25. */
  26. #include <linux/compiler.h>
  27. #include <linux/init.h>
  28. #include <linux/sched.h>
  29. #include <linux/slab.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/kernel_stat.h>
  32. #include <asm/irq.h>
  33. #include <asm/io.h>
  34. #include <asm/mips-boards/atlas.h>
  35. #include <asm/mips-boards/atlasint.h>
  36. #include <asm/gdb-stub.h>
  37. static struct atlas_ictrl_regs *atlas_hw0_icregs;
  38. extern asmlinkage void mipsIRQ(void);
  39. #if 0
  40. #define DEBUG_INT(x...) printk(x)
  41. #else
  42. #define DEBUG_INT(x...)
  43. #endif
  44. void disable_atlas_irq(unsigned int irq_nr)
  45. {
  46. atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE));
  47. iob();
  48. }
  49. void enable_atlas_irq(unsigned int irq_nr)
  50. {
  51. atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE));
  52. iob();
  53. }
  54. static unsigned int startup_atlas_irq(unsigned int irq)
  55. {
  56. enable_atlas_irq(irq);
  57. return 0; /* never anything pending */
  58. }
  59. #define shutdown_atlas_irq disable_atlas_irq
  60. #define mask_and_ack_atlas_irq disable_atlas_irq
  61. static void end_atlas_irq(unsigned int irq)
  62. {
  63. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  64. enable_atlas_irq(irq);
  65. }
  66. static struct hw_interrupt_type atlas_irq_type = {
  67. "Atlas",
  68. startup_atlas_irq,
  69. shutdown_atlas_irq,
  70. enable_atlas_irq,
  71. disable_atlas_irq,
  72. mask_and_ack_atlas_irq,
  73. end_atlas_irq,
  74. NULL
  75. };
  76. static inline int ls1bit32(unsigned int x)
  77. {
  78. int b = 31, s;
  79. s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
  80. s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s;
  81. s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s;
  82. s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s;
  83. s = 1; if (x << 1 == 0) s = 0; b -= s;
  84. return b;
  85. }
  86. void atlas_hw0_irqdispatch(struct pt_regs *regs)
  87. {
  88. unsigned long int_status;
  89. int irq;
  90. int_status = atlas_hw0_icregs->intstatus;
  91. /* if int_status == 0, then the interrupt has already been cleared */
  92. if (unlikely(int_status == 0))
  93. return;
  94. irq = ATLASINT_BASE + ls1bit32(int_status);
  95. DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
  96. do_IRQ(irq, regs);
  97. }
  98. void __init arch_init_irq(void)
  99. {
  100. int i;
  101. atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *));
  102. /*
  103. * Mask out all interrupt by writing "1" to all bit position in
  104. * the interrupt reset reg.
  105. */
  106. atlas_hw0_icregs->intrsten = 0xffffffff;
  107. /* Now safe to set the exception vector. */
  108. set_except_vector(0, mipsIRQ);
  109. for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
  110. irq_desc[i].status = IRQ_DISABLED;
  111. irq_desc[i].action = 0;
  112. irq_desc[i].depth = 1;
  113. irq_desc[i].handler = &atlas_irq_type;
  114. spin_lock_init(&irq_desc[i].lock);
  115. }
  116. }