intc_manager.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. *********************************************************************************************************
  3. * AR100 SYSTEM
  4. * AR100 Software System Develop Kits
  5. * interrupt manager
  6. *
  7. * (c) Copyright 2012-2016, Sunny China
  8. * All Rights Reserved
  9. *
  10. * File : interrupt_manager.c
  11. * By : Sunny
  12. * Version : v1.0
  13. * Date : 2012-5-3
  14. * Descript: the manager of interrupt.
  15. * Update : date auther ver notes
  16. * 2012-5-3 10:45:15 Sunny 1.0 Create this file.
  17. *********************************************************************************************************
  18. */
  19. #include <irqs.h>
  20. #include "intc_i.h"
  21. #include "platform-intc.h"
  22. s32 interrupt_clear_pending(u32 intno);
  23. struct int_isr_node isr_table[SUNXI_RINTC_IRQ_SOURCE_MAX];
  24. /*
  25. *********************************************************************************************************
  26. * INIT INTERRUPT MANAGER
  27. *
  28. * Description: initialize interrupt manager.
  29. *
  30. * Arguments : none.
  31. *
  32. * Returns : OK if initialize interrupt manager succeeded, others if failed.
  33. *********************************************************************************************************
  34. */
  35. s32 interrupt_init(void)
  36. {
  37. s32 index;
  38. /*initialize interrupt controller */
  39. intc_init();
  40. /*initialize ISR table */
  41. for (index = 0; index < SUNXI_RINTC_IRQ_SOURCE_MAX; index++) {
  42. isr_table[index].pisr = isr_default;
  43. isr_table[index].parg = NULL;
  44. }
  45. /*interrupt manager initialize succeeded */
  46. return OK;
  47. }
  48. /*
  49. *********************************************************************************************************
  50. * EXIT INTERRUPT MANAGER
  51. *
  52. * Description: exit interrupt manager.
  53. *
  54. * Arguments : none.
  55. *
  56. * Returns : OK if exit interrupt manager succeeded, others if failed.
  57. *********************************************************************************************************
  58. */
  59. s32 interrupt_exit(void)
  60. {
  61. intc_exit();
  62. return OK;
  63. }
  64. /*
  65. *********************************************************************************************************
  66. * ENABLE INTERRUPT
  67. *
  68. * Description: enable a specific interrupt.
  69. *
  70. * Arguments : intno : the number of interrupt which we want to enable.
  71. *
  72. * Returns : OK if enable interrupt succeeded, others if failed.
  73. *********************************************************************************************************
  74. */
  75. s32 interrupt_enable(u32 intno)
  76. {
  77. return intc_enable_interrupt(intno);
  78. }
  79. /*
  80. *********************************************************************************************************
  81. * DISABLE INTERRUPT
  82. *
  83. * Description: disable a specific interrupt.
  84. *
  85. * Arguments : intno : the number of interrupt which we want to disable.
  86. *
  87. * Returns : OK if disable interrupt succeeded, others if failed.
  88. *********************************************************************************************************
  89. */
  90. s32 interrupt_disable(u32 intno)
  91. {
  92. return intc_disable_interrupt(intno);
  93. }
  94. /*
  95. *********************************************************************************************************
  96. * SET NMI TRIGGER
  97. *
  98. * Description: set nmi trigger.
  99. *
  100. * Arguments : type : the trigger type.
  101. *
  102. * Returns : OK if set trigger type succeeded, others if failed.
  103. *********************************************************************************************************
  104. */
  105. s32 interrupt_set_nmi_trigger(u32 type)
  106. {
  107. u32 value;
  108. pintc_regs->control = type;
  109. /*mask cpus nmi irq */
  110. value = pintc_regs->mask;
  111. value |= 0x1;
  112. pintc_regs->mask = value;
  113. return OK;
  114. }
  115. s32 interrupt_set_mask(u32 intno, u32 mask)
  116. {
  117. return intc_set_mask(intno, mask);
  118. }
  119. s32 interrupt_set_group_config(u32 grp_irq_num, u32 mask)
  120. {
  121. return intc_set_group_config(grp_irq_num, mask);
  122. }
  123. /*
  124. *********************************************************************************************************
  125. * INSTALL ISR
  126. *
  127. * Description: install ISR for a specific interrupt.
  128. *
  129. * Arguments : intno : the number of interrupt which we want to install ISR.
  130. * pisr : the ISR which to been install.
  131. * parg : the argument for the ISR.
  132. *
  133. * Returns : OK if install ISR succeeded, others if failed.
  134. *
  135. * Note : the ISR execute entironment : CPU disable interrupt response.
  136. *********************************************************************************************************
  137. */
  138. s32 install_isr(u32 intno, __pISR_hdle_t pisr, void *parg)
  139. {
  140. /*intno can't beyond then IRQ_SOURCE_MAX */
  141. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  142. /*default isr, install directly */
  143. isr_table[intno].pisr = pisr;
  144. isr_table[intno].parg = parg;
  145. return OK;
  146. }
  147. /*
  148. *********************************************************************************************************
  149. * UNINSTALL ISR
  150. *
  151. * Description: uninstall ISR for a specific interrupt.
  152. *
  153. * Arguments : intno : the number of interrupt which we want to uninstall ISR.
  154. * pisr : the ISR which to been uninstall.
  155. *
  156. * Returns : OK if uninstall ISR succeeded, others if failed.
  157. *********************************************************************************************************
  158. */
  159. s32 uninstall_isr(u32 intno, __pISR_hdle_t pisr)
  160. {
  161. /*intno can't beyond then IRQ_SOURCE_MAX */
  162. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  163. if (isr_table[intno].pisr == pisr) {
  164. /*uninstall isr */
  165. isr_table[intno].pisr = isr_default;
  166. isr_table[intno].parg = NULL;
  167. } else {
  168. /*
  169. * don't support shared interrupt now,
  170. * by sunny at 2012-5-3 11:20:28.
  171. */
  172. return -1;
  173. }
  174. return OK;
  175. }
  176. /*
  177. *********************************************************************************************************
  178. * INTERRUPT ENTRY
  179. *
  180. * Description: the entry of CPU IRQ, mainly for CPU IRQ exception.
  181. *
  182. * Arguments : none.
  183. *
  184. * Returns : OK if process CPU IRQ succeeded, others if failed.
  185. *********************************************************************************************************
  186. */
  187. s32 interrupt_entry(void)
  188. {
  189. u32 intno = intc_get_current_interrupt();
  190. /*intno can't beyond then IRQ_SOURCE_MAX */
  191. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  192. /*
  193. * process interrupt by call isr,
  194. * not support shared intterrupt.
  195. */
  196. (isr_table[intno].pisr) (0, isr_table[intno].parg);
  197. return OK;
  198. }
  199. s32 interrupt_query_pending(u32 intno)
  200. {
  201. volatile u32 pending;
  202. if (intno <= 31)
  203. pending = pintc_regs->pending & (1 << intno);
  204. else if (intno > 31 && intno <= 63)
  205. pending = pintc_regs->pending1 & (1 << (intno - 32));
  206. else
  207. pending = pintc_regs->pending2 & (1 << (intno - 64));
  208. return pending;
  209. }
  210. s32 interrupt_clear_pending(u32 intno)
  211. {
  212. if (intno <= 31)
  213. pintc_regs->pending = (1 << intno);
  214. else if (intno > 31 && intno <= 63)
  215. pintc_regs->pending = (1 << (intno - 32));
  216. else
  217. pintc_regs->pending = (1 << (intno - 64));
  218. return OK;
  219. }
  220. s32 isr_default(int dummy, void *arg)
  221. {
  222. return true;
  223. }
  224. u32 interrupt_get_current_intno(void)
  225. {
  226. return intc_get_current_interrupt();
  227. }
  228. /*the backup of enable and mask register*/
  229. u32 intc_enable[3];
  230. u32 intc_mask[3];
  231. s32 interrupt_standby_enter(void)
  232. {
  233. /*backup registers */
  234. intc_enable[0] = pintc_regs->enable;
  235. intc_enable[1] = pintc_regs->enable1;
  236. intc_enable[2] = pintc_regs->enable2;
  237. intc_mask[0] = pintc_regs->mask;
  238. intc_mask[1] = pintc_regs->mask1;
  239. intc_mask[2] = pintc_regs->mask2;
  240. /*disable all interrupt */
  241. pintc_regs->enable = 0;
  242. pintc_regs->enable1 = 0;
  243. pintc_regs->enable2 = 0;
  244. pintc_regs->mask = 0;
  245. pintc_regs->mask1 = 0;
  246. pintc_regs->mask2 = 0;
  247. return OK;
  248. }
  249. s32 interrupt_standby_exit(void)
  250. {
  251. /*clear standby pendings */
  252. pintc_regs->pending = 0xffffffff;
  253. pintc_regs->pending1 = 0xffffffff;
  254. pintc_regs->pending2 = 0xffffffff;
  255. /*restore registers */
  256. pintc_regs->enable = intc_enable[0];
  257. pintc_regs->enable1 = intc_enable[1];
  258. pintc_regs->enable2 = intc_enable[2];
  259. pintc_regs->mask = intc_mask[0];
  260. pintc_regs->mask1 = intc_mask[1];
  261. pintc_regs->mask2 = intc_mask[2];
  262. return OK;
  263. }