interrupts.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * (C) Copyright 2000-2004
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * (C) Copyright 2007 Freescale Semiconductor Inc
  6. * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <watchdog.h>
  28. #include <asm/processor.h>
  29. #include <asm/immap.h>
  30. #define NR_IRQS (CFG_NUM_IRQS)
  31. /*
  32. * Interrupt vector functions.
  33. */
  34. struct interrupt_action {
  35. interrupt_handler_t *handler;
  36. void *arg;
  37. };
  38. static struct interrupt_action irq_vecs[NR_IRQS];
  39. static __inline__ unsigned short get_sr (void)
  40. {
  41. unsigned short sr;
  42. asm volatile ("move.w %%sr,%0":"=r" (sr):);
  43. return sr;
  44. }
  45. static __inline__ void set_sr (unsigned short sr)
  46. {
  47. asm volatile ("move.w %0,%%sr"::"r" (sr));
  48. }
  49. /************************************************************************/
  50. /*
  51. * Install and free an interrupt handler
  52. */
  53. void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
  54. {
  55. if ((vec < 0) || (vec > NR_IRQS)) {
  56. printf ("irq_install_handler: wrong interrupt vector %d\n",
  57. vec);
  58. return;
  59. }
  60. irq_vecs[vec].handler = handler;
  61. irq_vecs[vec].arg = arg;
  62. }
  63. void irq_free_handler (int vec)
  64. {
  65. if ((vec < 0) || (vec > NR_IRQS)) {
  66. return;
  67. }
  68. irq_vecs[vec].handler = NULL;
  69. irq_vecs[vec].arg = NULL;
  70. }
  71. void enable_interrupts (void)
  72. {
  73. unsigned short sr;
  74. sr = get_sr ();
  75. set_sr (sr & ~0x0700);
  76. }
  77. int disable_interrupts (void)
  78. {
  79. unsigned short sr;
  80. sr = get_sr ();
  81. set_sr (sr | 0x0700);
  82. return ((sr & 0x0700) == 0); /* return TRUE, if interrupts were enabled before */
  83. }
  84. void int_handler (struct pt_regs *fp)
  85. {
  86. int vec;
  87. vec = (fp->vector >> 2) & 0xff;
  88. if (vec > 0x40)
  89. vec -= 0x40;
  90. if (irq_vecs[vec].handler != NULL) {
  91. irq_vecs[vec].handler (irq_vecs[vec].arg);
  92. } else {
  93. printf ("\nBogus External Interrupt Vector %d\n", vec);
  94. }
  95. }