irq.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2011 Zhang, Keguang <[email protected]>
  4. */
  5. #include <linux/interrupt.h>
  6. #include <linux/irq.h>
  7. #include <asm/irq_cpu.h>
  8. #include <loongson1.h>
  9. #include <irq.h>
  10. #define LS1X_INTC_REG(n, x) \
  11. ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x)))
  12. #define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0)
  13. #define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4)
  14. #define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8)
  15. #define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc)
  16. #define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10)
  17. #define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14)
  18. static void ls1x_irq_ack(struct irq_data *d)
  19. {
  20. unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
  21. unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
  22. __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
  23. | (1 << bit), LS1X_INTC_INTCLR(n));
  24. }
  25. static void ls1x_irq_mask(struct irq_data *d)
  26. {
  27. unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
  28. unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
  29. __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
  30. & ~(1 << bit), LS1X_INTC_INTIEN(n));
  31. }
  32. static void ls1x_irq_mask_ack(struct irq_data *d)
  33. {
  34. unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
  35. unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
  36. __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
  37. & ~(1 << bit), LS1X_INTC_INTIEN(n));
  38. __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
  39. | (1 << bit), LS1X_INTC_INTCLR(n));
  40. }
  41. static void ls1x_irq_unmask(struct irq_data *d)
  42. {
  43. unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
  44. unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
  45. __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
  46. | (1 << bit), LS1X_INTC_INTIEN(n));
  47. }
  48. static int ls1x_irq_settype(struct irq_data *d, unsigned int type)
  49. {
  50. unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
  51. unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
  52. switch (type) {
  53. case IRQ_TYPE_LEVEL_HIGH:
  54. __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
  55. | (1 << bit), LS1X_INTC_INTPOL(n));
  56. __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
  57. & ~(1 << bit), LS1X_INTC_INTEDGE(n));
  58. break;
  59. case IRQ_TYPE_LEVEL_LOW:
  60. __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
  61. & ~(1 << bit), LS1X_INTC_INTPOL(n));
  62. __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
  63. & ~(1 << bit), LS1X_INTC_INTEDGE(n));
  64. break;
  65. case IRQ_TYPE_EDGE_RISING:
  66. __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
  67. | (1 << bit), LS1X_INTC_INTPOL(n));
  68. __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
  69. | (1 << bit), LS1X_INTC_INTEDGE(n));
  70. break;
  71. case IRQ_TYPE_EDGE_FALLING:
  72. __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
  73. & ~(1 << bit), LS1X_INTC_INTPOL(n));
  74. __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
  75. | (1 << bit), LS1X_INTC_INTEDGE(n));
  76. break;
  77. case IRQ_TYPE_EDGE_BOTH:
  78. __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
  79. & ~(1 << bit), LS1X_INTC_INTPOL(n));
  80. __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
  81. | (1 << bit), LS1X_INTC_INTEDGE(n));
  82. break;
  83. case IRQ_TYPE_NONE:
  84. break;
  85. default:
  86. return -EINVAL;
  87. }
  88. return 0;
  89. }
  90. static struct irq_chip ls1x_irq_chip = {
  91. .name = "LS1X-INTC",
  92. .irq_ack = ls1x_irq_ack,
  93. .irq_mask = ls1x_irq_mask,
  94. .irq_mask_ack = ls1x_irq_mask_ack,
  95. .irq_unmask = ls1x_irq_unmask,
  96. .irq_set_type = ls1x_irq_settype,
  97. };
  98. static void ls1x_irq_dispatch(int n)
  99. {
  100. u32 int_status, irq;
  101. /* Get pending sources, masked by current enables */
  102. int_status = __raw_readl(LS1X_INTC_INTISR(n)) &
  103. __raw_readl(LS1X_INTC_INTIEN(n));
  104. if (int_status) {
  105. irq = LS1X_IRQ(n, __ffs(int_status));
  106. do_IRQ(irq);
  107. }
  108. }
  109. asmlinkage void plat_irq_dispatch(void)
  110. {
  111. unsigned int pending;
  112. pending = read_c0_cause() & read_c0_status() & ST0_IM;
  113. if (pending & CAUSEF_IP7)
  114. do_IRQ(TIMER_IRQ);
  115. else if (pending & CAUSEF_IP2)
  116. ls1x_irq_dispatch(0); /* INT0 */
  117. else if (pending & CAUSEF_IP3)
  118. ls1x_irq_dispatch(1); /* INT1 */
  119. else if (pending & CAUSEF_IP4)
  120. ls1x_irq_dispatch(2); /* INT2 */
  121. else if (pending & CAUSEF_IP5)
  122. ls1x_irq_dispatch(3); /* INT3 */
  123. else if (pending & CAUSEF_IP6)
  124. ls1x_irq_dispatch(4); /* INT4 */
  125. else
  126. spurious_interrupt();
  127. }
  128. static void __init ls1x_irq_init(int base)
  129. {
  130. int n;
  131. /* Disable interrupts and clear pending,
  132. * setup all IRQs as high level triggered
  133. */
  134. for (n = 0; n < INTN; n++) {
  135. __raw_writel(0x0, LS1X_INTC_INTIEN(n));
  136. __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n));
  137. __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n));
  138. /* set DMA0, DMA1 and DMA2 to edge trigger */
  139. __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n));
  140. }
  141. for (n = base; n < NR_IRQS; n++) {
  142. irq_set_chip_and_handler(n, &ls1x_irq_chip,
  143. handle_level_irq);
  144. }
  145. if (request_irq(INT0_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
  146. pr_err("Failed to request irq %d (cascade)\n", INT0_IRQ);
  147. if (request_irq(INT1_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
  148. pr_err("Failed to request irq %d (cascade)\n", INT1_IRQ);
  149. if (request_irq(INT2_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
  150. pr_err("Failed to request irq %d (cascade)\n", INT2_IRQ);
  151. if (request_irq(INT3_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
  152. pr_err("Failed to request irq %d (cascade)\n", INT3_IRQ);
  153. #if defined(CONFIG_LOONGSON1_LS1C)
  154. if (request_irq(INT4_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
  155. pr_err("Failed to request irq %d (cascade)\n", INT4_IRQ);
  156. #endif
  157. }
  158. void __init arch_init_irq(void)
  159. {
  160. mips_cpu_irq_init();
  161. ls1x_irq_init(LS1X_IRQ_BASE);
  162. }