interrupts.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2004
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (C) Copyright 2007 Freescale Semiconductor Inc
  7. * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
  8. */
  9. #include <common.h>
  10. #include <irq_func.h>
  11. #include <watchdog.h>
  12. #include <asm/processor.h>
  13. #include <asm/immap.h>
  14. #include <asm/ptrace.h>
  15. #define NR_IRQS (CONFIG_SYS_NUM_IRQS)
  16. /*
  17. * Interrupt vector functions.
  18. */
  19. struct interrupt_action {
  20. interrupt_handler_t *handler;
  21. void *arg;
  22. };
  23. static struct interrupt_action irq_vecs[NR_IRQS];
  24. static __inline__ unsigned short get_sr (void)
  25. {
  26. unsigned short sr;
  27. asm volatile ("move.w %%sr,%0":"=r" (sr):);
  28. return sr;
  29. }
  30. static __inline__ void set_sr (unsigned short sr)
  31. {
  32. asm volatile ("move.w %0,%%sr"::"r" (sr));
  33. }
  34. /************************************************************************/
  35. /*
  36. * Install and free an interrupt handler
  37. */
  38. void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
  39. {
  40. if ((vec < 0) || (vec >= NR_IRQS)) {
  41. printf ("irq_install_handler: wrong interrupt vector %d\n",
  42. vec);
  43. return;
  44. }
  45. irq_vecs[vec].handler = handler;
  46. irq_vecs[vec].arg = arg;
  47. }
  48. void irq_free_handler(int vec)
  49. {
  50. if ((vec < 0) || (vec >= NR_IRQS)) {
  51. return;
  52. }
  53. irq_vecs[vec].handler = NULL;
  54. irq_vecs[vec].arg = NULL;
  55. }
  56. void enable_interrupts(void)
  57. {
  58. unsigned short sr;
  59. sr = get_sr ();
  60. set_sr (sr & ~0x0700);
  61. }
  62. int disable_interrupts(void)
  63. {
  64. unsigned short sr;
  65. sr = get_sr ();
  66. set_sr (sr | 0x0700);
  67. return ((sr & 0x0700) == 0); /* return true, if interrupts were enabled before */
  68. }
  69. void int_handler (struct pt_regs *fp)
  70. {
  71. int vec;
  72. vec = (fp->vector >> 2) & 0xff;
  73. if (vec > 0x40)
  74. vec -= 0x40;
  75. if (irq_vecs[vec].handler != NULL) {
  76. irq_vecs[vec].handler (irq_vecs[vec].arg);
  77. } else {
  78. printf ("\nBogus External Interrupt Vector %d\n", vec);
  79. }
  80. }