irq.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/arm/mach-sa1100/irq.c
  3.  *
  4.  * Copyright (C) 1999-2001 Nicolas Pitre
  5.  *
  6.  * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing.
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License version 2 as
  10.  * published by the Free Software Foundation.
  11.  */
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/sched.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/ioport.h>
  17. #include <linux/ptrace.h>
  18. #include <asm/hardware.h>
  19. #include <asm/irq.h>
  20. #include <asm/mach/irq.h>
  21. #include <asm/arch/irq.h>
  22. #include "generic.h"
  23. /*
  24.  * SA1100 GPIO edge detection for IRQs:
  25.  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
  26.  * This must be called *before* the appropriate IRQ is registered.
  27.  * Use this instead of directly setting GRER/GFER.
  28.  */
  29. static int GPIO_IRQ_rising_edge;
  30. static int GPIO_IRQ_falling_edge;
  31. void set_GPIO_IRQ_edge(int gpio_mask, int edge)
  32. {
  33. long flags;
  34. int irq = 0;
  35. gpio_mask &= 0x0fffffff;
  36. local_irq_save(flags);
  37. if (edge & GPIO_FALLING_EDGE)
  38. GPIO_IRQ_falling_edge |= gpio_mask;
  39. else
  40. GPIO_IRQ_falling_edge &= ~gpio_mask;
  41. if (edge & GPIO_RISING_EDGE)
  42. GPIO_IRQ_rising_edge |= gpio_mask;
  43. else
  44. GPIO_IRQ_rising_edge &= ~gpio_mask;
  45. GPDR &= ~gpio_mask;
  46. GAFR &= ~gpio_mask;
  47. while (gpio_mask) {
  48. if (irq == 11)
  49. irq = IRQ_GPIO11;
  50. if (gpio_mask & 1)
  51. irq_desc[irq].valid = 1;
  52. irq++;
  53. gpio_mask >>= 1;
  54. }
  55. local_irq_restore(flags);
  56. }
  57. EXPORT_SYMBOL(set_GPIO_IRQ_edge);
  58. /*
  59.  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
  60.  * this is for internal IRQs i.e. from 11 to 31.
  61.  */
  62. static void sa1100_mask_irq(unsigned int irq)
  63. {
  64. ICMR &= ~(1 << irq);
  65. }
  66. static void sa1100_unmask_irq(unsigned int irq)
  67. {
  68. ICMR |= (1 << irq);
  69. }
  70. /*
  71.  * GPIO IRQs must be acknoledged.  This is for IRQs from 0 to 10.
  72.  */
  73. static void sa1100_mask_and_ack_GPIO0_10_irq(unsigned int irq)
  74. {
  75. ICMR &= ~(1 << irq);
  76. GEDR = (1 << irq);
  77. }
  78. static void sa1100_mask_GPIO0_10_irq(unsigned int irq)
  79. {
  80. ICMR &= ~(1 << irq);
  81. }
  82. static void sa1100_unmask_GPIO0_10_irq(unsigned int irq)
  83. {
  84. GRER = (GRER & ~(1 << irq)) | (GPIO_IRQ_rising_edge & (1 << irq));
  85. GFER = (GFER & ~(1 << irq)) | (GPIO_IRQ_falling_edge & (1 << irq));
  86. ICMR |= (1 << irq);
  87. }
  88. /*
  89.  * Install handler for GPIO 11-27 edge detect interrupts
  90.  */
  91. static int GPIO_11_27_enabled; /* enabled i.e. unmasked GPIO IRQs */
  92. static int GPIO_11_27_spurious; /* GPIOs that triggered when masked */
  93. static void sa1100_GPIO11_27_demux(int irq, void *dev_id,
  94.    struct pt_regs *regs)
  95. {
  96. int i, spurious;
  97. while ((irq = (GEDR & 0xfffff800))) {
  98. /*
  99.  * We don't want to clear GRER/GFER when the corresponding
  100.  * IRQ is masked because we could miss a level transition
  101.  * i.e. an IRQ which need servicing as soon as it is
  102.  * unmasked.  However, such situation should happen only
  103.  * during the loop below.  Thus all IRQs which aren't
  104.  * enabled at this point are considered spurious.  Those
  105.  * are cleared but only de-activated if they happen twice.
  106.  */
  107. spurious = irq & ~GPIO_11_27_enabled;
  108. if (spurious) {
  109. GEDR = spurious;
  110. GRER &= ~(spurious & GPIO_11_27_spurious);
  111. GFER &= ~(spurious & GPIO_11_27_spurious);
  112. GPIO_11_27_spurious |= spurious;
  113. irq ^= spurious;
  114. if (!irq) continue;
  115. }
  116. for (i = 11; i <= 27; ++i) {
  117. if (irq & (1<<i)) {
  118. do_IRQ(IRQ_GPIO11 + i - 11, regs);
  119. }
  120. }
  121. }
  122. }
  123. static struct irqaction GPIO11_27_irq = {
  124. name: "GPIO 11-27",
  125. handler: sa1100_GPIO11_27_demux,
  126. flags: SA_INTERRUPT
  127. };
  128. static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq)
  129. {
  130. int mask = (1 << GPIO_11_27_IRQ(irq));
  131. GPIO_11_27_spurious &= ~mask;
  132. GPIO_11_27_enabled &= ~mask;
  133. GEDR = mask;
  134. }
  135. static void sa1100_mask_GPIO11_27_irq(unsigned int irq)
  136. {
  137. int mask = (1 << GPIO_11_27_IRQ(irq));
  138. GPIO_11_27_spurious &= ~mask;
  139. GPIO_11_27_enabled &= ~mask;
  140. }
  141. static void sa1100_unmask_GPIO11_27_irq(unsigned int irq)
  142. {
  143. int mask = (1 << GPIO_11_27_IRQ(irq));
  144. if (GPIO_11_27_spurious & mask) {
  145. /*
  146.  * We don't want to miss an interrupt that would have occurred
  147.  * while it was masked.  Simulate it if it is the case.
  148.  */
  149. int state = GPLR;
  150. if (((state & GPIO_IRQ_rising_edge) |
  151.      (~state & GPIO_IRQ_falling_edge)) & mask)
  152. {
  153. /* just in case it gets referenced: */
  154. struct pt_regs dummy;
  155. memzero(&dummy, sizeof(dummy));
  156. do_IRQ(irq, &dummy);
  157. /* we are being called recursively from do_IRQ() */
  158. return;
  159. }
  160. }
  161. GPIO_11_27_enabled |= mask;
  162. GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask);
  163. GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
  164. }
  165. static struct resource irq_resource = {
  166. name: "irqs",
  167. start: 0x90050000,
  168. end: 0x9005ffff,
  169. };
  170. void __init sa1100_init_irq(void)
  171. {
  172. int irq;
  173. request_resource(&iomem_resource, &irq_resource);
  174. /* disable all IRQs */
  175. ICMR = 0;
  176. /* all IRQs are IRQ, not FIQ */
  177. ICLR = 0;
  178. /* clear all GPIO edge detects */
  179. GFER = 0;
  180. GRER = 0;
  181. GEDR = -1;
  182. /*
  183.  * Whatever the doc says, this has to be set for the wait-on-irq
  184.  * instruction to work... on a SA1100 rev 9 at least.
  185.  */
  186. ICCR = 1;
  187. /*
  188.  * Note: GPIO IRQs are initially invalid until at least one call
  189.  * to set_GPIO_IRQ_edge() is performed.
  190.  */
  191. for (irq = 0; irq <= 10; irq++) {
  192. irq_desc[irq].valid = 0;
  193. irq_desc[irq].probe_ok = 1;
  194. irq_desc[irq].mask_ack = sa1100_mask_and_ack_GPIO0_10_irq;
  195. irq_desc[irq].mask = sa1100_mask_GPIO0_10_irq;
  196. irq_desc[irq].unmask = sa1100_unmask_GPIO0_10_irq;
  197. }
  198. for (irq = 11; irq <= 31; irq++) {
  199. irq_desc[irq].valid = 1;
  200. irq_desc[irq].probe_ok = 0;
  201. irq_desc[irq].mask_ack = sa1100_mask_irq;
  202. irq_desc[irq].mask = sa1100_mask_irq;
  203. irq_desc[irq].unmask = sa1100_unmask_irq;
  204. }
  205. for (irq = 32; irq <= 48; irq++) {
  206. irq_desc[irq].valid = 0;
  207. irq_desc[irq].probe_ok = 1;
  208. irq_desc[irq].mask_ack = sa1100_mask_and_ack_GPIO11_27_irq;
  209. irq_desc[irq].mask = sa1100_mask_GPIO11_27_irq;
  210. irq_desc[irq].unmask = sa1100_unmask_GPIO11_27_irq;
  211. }
  212. setup_arm_irq( IRQ_GPIO11_27, &GPIO11_27_irq );
  213. /*
  214.  * We generally don't want the LCD IRQ being
  215.  * enabled as soon as we request it.
  216.  */
  217. irq_desc[IRQ_LCD].noautoenable = 1;
  218. }