irq.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * linux/arch/arm/mach-pxa/irq.c
  3. *
  4. * Generic PXA IRQ handling
  5. *
  6. * Author: Nicolas Pitre
  7. * Created: Jun 15, 2001
  8. * Copyright: MontaVista Software Inc.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/sysdev.h>
  18. #include <asm/hardware.h>
  19. #include <asm/irq.h>
  20. #include <asm/mach/irq.h>
  21. #include <asm/arch/pxa-regs.h>
  22. #include <asm/arch/pxa2xx-gpio.h>
  23. #include "generic.h"
  24. #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
  25. #define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
  26. #define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
  27. /*
  28. * This is for peripheral IRQs internal to the PXA chip.
  29. */
  30. static int pxa_internal_irq_nr;
  31. static void pxa_mask_irq(unsigned int irq)
  32. {
  33. _ICMR(irq) &= ~(1 << IRQ_BIT(irq));
  34. }
  35. static void pxa_unmask_irq(unsigned int irq)
  36. {
  37. _ICMR(irq) |= 1 << IRQ_BIT(irq);
  38. }
  39. static struct irq_chip pxa_internal_irq_chip = {
  40. .name = "SC",
  41. .ack = pxa_mask_irq,
  42. .mask = pxa_mask_irq,
  43. .unmask = pxa_unmask_irq,
  44. };
  45. void __init pxa_init_irq(int irq_nr, set_wake_t fn)
  46. {
  47. int irq;
  48. pxa_internal_irq_nr = irq_nr;
  49. for (irq = 0; irq < irq_nr; irq += 32) {
  50. _ICMR(irq) = 0; /* disable all IRQs */
  51. _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
  52. }
  53. /* only unmasked interrupts kick us out of idle */
  54. ICCR = 1;
  55. for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
  56. set_irq_chip(irq, &pxa_internal_irq_chip);
  57. set_irq_handler(irq, handle_level_irq);
  58. set_irq_flags(irq, IRQF_VALID);
  59. }
  60. pxa_internal_irq_chip.set_wake = fn;
  61. }
  62. #ifdef CONFIG_PM
  63. static unsigned long saved_icmr[2];
  64. static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
  65. {
  66. int i, irq = PXA_IRQ(0);
  67. for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
  68. saved_icmr[i] = _ICMR(irq);
  69. _ICMR(irq) = 0;
  70. }
  71. return 0;
  72. }
  73. static int pxa_irq_resume(struct sys_device *dev)
  74. {
  75. int i, irq = PXA_IRQ(0);
  76. for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
  77. _ICMR(irq) = saved_icmr[i];
  78. _ICLR(irq) = 0;
  79. }
  80. ICCR = 1;
  81. return 0;
  82. }
  83. #else
  84. #define pxa_irq_suspend NULL
  85. #define pxa_irq_resume NULL
  86. #endif
  87. struct sysdev_class pxa_irq_sysclass = {
  88. .name = "irq",
  89. .suspend = pxa_irq_suspend,
  90. .resume = pxa_irq_resume,
  91. };
  92. static int __init pxa_irq_init(void)
  93. {
  94. return sysdev_class_register(&pxa_irq_sysclass);
  95. }
  96. core_initcall(pxa_irq_init);