irq.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/arch/sh/boards/se/7206/irq.c
  4. *
  5. * Copyright (C) 2005,2006 Yoshinori Sato
  6. *
  7. * Hitachi SolutionEngine Support.
  8. *
  9. */
  10. #include <linux/init.h>
  11. #include <linux/irq.h>
  12. #include <linux/io.h>
  13. #include <linux/interrupt.h>
  14. #include <mach-se/mach/se7206.h>
  15. #define INTSTS0 0x31800000
  16. #define INTSTS1 0x31800002
  17. #define INTMSK0 0x31800004
  18. #define INTMSK1 0x31800006
  19. #define INTSEL 0x31800008
  20. #define IRQ0_IRQ 64
  21. #define IRQ1_IRQ 65
  22. #define IRQ3_IRQ 67
  23. #define INTC_IPR01 0xfffe0818
  24. #define INTC_ICR1 0xfffe0802
  25. static void disable_se7206_irq(struct irq_data *data)
  26. {
  27. unsigned int irq = data->irq;
  28. unsigned short val;
  29. unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
  30. unsigned short msk0,msk1;
  31. /* Set the priority in IPR to 0 */
  32. val = __raw_readw(INTC_IPR01);
  33. val &= mask;
  34. __raw_writew(val, INTC_IPR01);
  35. /* FPGA mask set */
  36. msk0 = __raw_readw(INTMSK0);
  37. msk1 = __raw_readw(INTMSK1);
  38. switch (irq) {
  39. case IRQ0_IRQ:
  40. msk0 |= 0x0010;
  41. break;
  42. case IRQ1_IRQ:
  43. msk0 |= 0x000f;
  44. break;
  45. case IRQ3_IRQ:
  46. msk0 |= 0x0f00;
  47. msk1 |= 0x00ff;
  48. break;
  49. }
  50. __raw_writew(msk0, INTMSK0);
  51. __raw_writew(msk1, INTMSK1);
  52. }
  53. static void enable_se7206_irq(struct irq_data *data)
  54. {
  55. unsigned int irq = data->irq;
  56. unsigned short val;
  57. unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
  58. unsigned short msk0,msk1;
  59. /* Set priority in IPR back to original value */
  60. val = __raw_readw(INTC_IPR01);
  61. val |= value;
  62. __raw_writew(val, INTC_IPR01);
  63. /* FPGA mask reset */
  64. msk0 = __raw_readw(INTMSK0);
  65. msk1 = __raw_readw(INTMSK1);
  66. switch (irq) {
  67. case IRQ0_IRQ:
  68. msk0 &= ~0x0010;
  69. break;
  70. case IRQ1_IRQ:
  71. msk0 &= ~0x000f;
  72. break;
  73. case IRQ3_IRQ:
  74. msk0 &= ~0x0f00;
  75. msk1 &= ~0x00ff;
  76. break;
  77. }
  78. __raw_writew(msk0, INTMSK0);
  79. __raw_writew(msk1, INTMSK1);
  80. }
  81. static void eoi_se7206_irq(struct irq_data *data)
  82. {
  83. unsigned short sts0,sts1;
  84. unsigned int irq = data->irq;
  85. if (!irqd_irq_disabled(data) && !irqd_irq_inprogress(data))
  86. enable_se7206_irq(data);
  87. /* FPGA isr clear */
  88. sts0 = __raw_readw(INTSTS0);
  89. sts1 = __raw_readw(INTSTS1);
  90. switch (irq) {
  91. case IRQ0_IRQ:
  92. sts0 &= ~0x0010;
  93. break;
  94. case IRQ1_IRQ:
  95. sts0 &= ~0x000f;
  96. break;
  97. case IRQ3_IRQ:
  98. sts0 &= ~0x0f00;
  99. sts1 &= ~0x00ff;
  100. break;
  101. }
  102. __raw_writew(sts0, INTSTS0);
  103. __raw_writew(sts1, INTSTS1);
  104. }
  105. static struct irq_chip se7206_irq_chip __read_mostly = {
  106. .name = "SE7206-FPGA",
  107. .irq_mask = disable_se7206_irq,
  108. .irq_unmask = enable_se7206_irq,
  109. .irq_eoi = eoi_se7206_irq,
  110. };
  111. static void make_se7206_irq(unsigned int irq)
  112. {
  113. disable_irq_nosync(irq);
  114. irq_set_chip_and_handler_name(irq, &se7206_irq_chip,
  115. handle_level_irq, "level");
  116. disable_se7206_irq(irq_get_irq_data(irq));
  117. }
  118. /*
  119. * Initialize IRQ setting
  120. */
  121. void __init init_se7206_IRQ(void)
  122. {
  123. make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
  124. make_se7206_irq(IRQ1_IRQ); /* ATA */
  125. make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
  126. __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
  127. /* FPGA System register setup*/
  128. __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
  129. __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */
  130. /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
  131. __raw_writew(0x0001,INTSEL);
  132. }