irq.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * arch/arm/mach-orion5x/irq.c
  3. *
  4. * Core IRQ functions for Marvell Orion System On Chip
  5. *
  6. * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public
  9. * License version 2. This program is licensed "as is" without any
  10. * warranty of any kind, whether express or implied.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/irq.h>
  15. #include <linux/io.h>
  16. #include <asm/gpio.h>
  17. #include <mach/orion5x.h>
  18. #include <plat/irq.h>
  19. #include "common.h"
  20. /*****************************************************************************
  21. * Orion GPIO IRQ
  22. *
  23. * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same
  24. * value of the line or the opposite value.
  25. *
  26. * Level IRQ handlers: DATA_IN is used directly as cause register.
  27. * Interrupt are masked by LEVEL_MASK registers.
  28. * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE.
  29. * Interrupt are masked by EDGE_MASK registers.
  30. * Both-edge handlers: Similar to regular Edge handlers, but also swaps
  31. * the polarity to catch the next line transaction.
  32. * This is a race condition that might not perfectly
  33. * work on some use cases.
  34. *
  35. * Every eight GPIO lines are grouped (OR'ed) before going up to main
  36. * cause register.
  37. *
  38. * EDGE cause mask
  39. * data-in /--------| |-----| |----\
  40. * -----| |----- ---- to main cause reg
  41. * X \----------------| |----/
  42. * polarity LEVEL mask
  43. *
  44. ****************************************************************************/
  45. static void orion5x_gpio_irq_ack(u32 irq)
  46. {
  47. int pin = irq_to_gpio(irq);
  48. if (irq_desc[irq].status & IRQ_LEVEL)
  49. /*
  50. * Mask bit for level interrupt
  51. */
  52. orion5x_clrbits(GPIO_LEVEL_MASK, 1 << pin);
  53. else
  54. /*
  55. * Clear casue bit for egde interrupt
  56. */
  57. orion5x_clrbits(GPIO_EDGE_CAUSE, 1 << pin);
  58. }
  59. static void orion5x_gpio_irq_mask(u32 irq)
  60. {
  61. int pin = irq_to_gpio(irq);
  62. if (irq_desc[irq].status & IRQ_LEVEL)
  63. orion5x_clrbits(GPIO_LEVEL_MASK, 1 << pin);
  64. else
  65. orion5x_clrbits(GPIO_EDGE_MASK, 1 << pin);
  66. }
  67. static void orion5x_gpio_irq_unmask(u32 irq)
  68. {
  69. int pin = irq_to_gpio(irq);
  70. if (irq_desc[irq].status & IRQ_LEVEL)
  71. orion5x_setbits(GPIO_LEVEL_MASK, 1 << pin);
  72. else
  73. orion5x_setbits(GPIO_EDGE_MASK, 1 << pin);
  74. }
  75. static int orion5x_gpio_set_irq_type(u32 irq, u32 type)
  76. {
  77. int pin = irq_to_gpio(irq);
  78. struct irq_desc *desc;
  79. if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) {
  80. printk(KERN_ERR "orion5x_gpio_set_irq_type failed "
  81. "(irq %d, pin %d).\n", irq, pin);
  82. return -EINVAL;
  83. }
  84. desc = irq_desc + irq;
  85. switch (type) {
  86. case IRQ_TYPE_LEVEL_HIGH:
  87. desc->handle_irq = handle_level_irq;
  88. desc->status |= IRQ_LEVEL;
  89. orion5x_clrbits(GPIO_IN_POL, (1 << pin));
  90. break;
  91. case IRQ_TYPE_LEVEL_LOW:
  92. desc->handle_irq = handle_level_irq;
  93. desc->status |= IRQ_LEVEL;
  94. orion5x_setbits(GPIO_IN_POL, (1 << pin));
  95. break;
  96. case IRQ_TYPE_EDGE_RISING:
  97. desc->handle_irq = handle_edge_irq;
  98. desc->status &= ~IRQ_LEVEL;
  99. orion5x_clrbits(GPIO_IN_POL, (1 << pin));
  100. break;
  101. case IRQ_TYPE_EDGE_FALLING:
  102. desc->handle_irq = handle_edge_irq;
  103. desc->status &= ~IRQ_LEVEL;
  104. orion5x_setbits(GPIO_IN_POL, (1 << pin));
  105. break;
  106. case IRQ_TYPE_EDGE_BOTH:
  107. desc->handle_irq = handle_edge_irq;
  108. desc->status &= ~IRQ_LEVEL;
  109. /*
  110. * set initial polarity based on current input level
  111. */
  112. if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN))
  113. & (1 << pin))
  114. orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
  115. else
  116. orion5x_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */
  117. break;
  118. default:
  119. printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
  120. return -EINVAL;
  121. }
  122. desc->status &= ~IRQ_TYPE_SENSE_MASK;
  123. desc->status |= type & IRQ_TYPE_SENSE_MASK;
  124. return 0;
  125. }
  126. static struct irq_chip orion5x_gpio_irq_chip = {
  127. .name = "Orion-IRQ-GPIO",
  128. .ack = orion5x_gpio_irq_ack,
  129. .mask = orion5x_gpio_irq_mask,
  130. .unmask = orion5x_gpio_irq_unmask,
  131. .set_type = orion5x_gpio_set_irq_type,
  132. };
  133. static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
  134. {
  135. u32 cause, offs, pin;
  136. BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);
  137. offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8;
  138. cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) |
  139. (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK));
  140. for (pin = offs; pin < offs + 8; pin++) {
  141. if (cause & (1 << pin)) {
  142. irq = gpio_to_irq(pin);
  143. desc = irq_desc + irq;
  144. if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
  145. /* Swap polarity (race with GPIO line) */
  146. u32 polarity = readl(GPIO_IN_POL);
  147. polarity ^= 1 << pin;
  148. writel(polarity, GPIO_IN_POL);
  149. }
  150. generic_handle_irq(irq);
  151. }
  152. }
  153. }
  154. static void __init orion5x_init_gpio_irq(void)
  155. {
  156. int i;
  157. struct irq_desc *desc;
  158. /*
  159. * Mask and clear GPIO IRQ interrupts
  160. */
  161. writel(0x0, GPIO_LEVEL_MASK);
  162. writel(0x0, GPIO_EDGE_MASK);
  163. writel(0x0, GPIO_EDGE_CAUSE);
  164. /*
  165. * Register chained level handlers for GPIO IRQs by default.
  166. * User can use set_type() if he wants to use edge types handlers.
  167. */
  168. for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) {
  169. set_irq_chip(i, &orion5x_gpio_irq_chip);
  170. set_irq_handler(i, handle_level_irq);
  171. desc = irq_desc + i;
  172. desc->status |= IRQ_LEVEL;
  173. set_irq_flags(i, IRQF_VALID);
  174. }
  175. set_irq_chained_handler(IRQ_ORION5X_GPIO_0_7, orion5x_gpio_irq_handler);
  176. set_irq_chained_handler(IRQ_ORION5X_GPIO_8_15, orion5x_gpio_irq_handler);
  177. set_irq_chained_handler(IRQ_ORION5X_GPIO_16_23, orion5x_gpio_irq_handler);
  178. set_irq_chained_handler(IRQ_ORION5X_GPIO_24_31, orion5x_gpio_irq_handler);
  179. }
  180. /*****************************************************************************
  181. * Orion Main IRQ
  182. ****************************************************************************/
  183. static void __init orion5x_init_main_irq(void)
  184. {
  185. orion_irq_init(0, (void __iomem *)MAIN_IRQ_MASK);
  186. }
  187. void __init orion5x_init_irq(void)
  188. {
  189. orion5x_init_main_irq();
  190. orion5x_init_gpio_irq();
  191. }