1 /* 2 ********************************************************************************************************* 3 * AR100 SYSTEM 4 * AR100 Software System Develop Kits 5 * interrupt module 6 * 7 * (c) Copyright 2012-2016, Sunny China 8 * All Rights Reserved 9 * 10 * File : intc.c 11 * By : Sunny 12 * Version : v1.0 13 * Date : 2012-5-3 14 * Descript: interrupt controller module. 15 * Update : date auther ver notes 16 * 2012-5-3 13:25:40 Sunny 1.0 Create this file. 17 ********************************************************************************************************* 18 */ 19 20 #include "intc_i.h" 21 #include "platform-intc.h" 22 23 struct intc_regs *pintc_regs; 24 25 /* 26 ********************************************************************************************************* 27 * INTERRUPT INIT 28 * 29 * Description: initialize interrupt. 30 * 31 * Arguments : none. 32 * 33 * Returns : OK if initialize succeeded, others if failed. 34 * 35 * Note : 36 ********************************************************************************************************* 37 */ intc_init(void)38s32 intc_init(void) 39 { 40 pintc_regs = (struct intc_regs *)(SUNXI_R_INTC_PBASE); 41 42 /*initialize interrupt controller */ 43 pintc_regs->enable = 0x0; 44 pintc_regs->mask = 0x0; 45 pintc_regs->pending = 0xffffffff; 46 47 pintc_regs->enable1 = 0x0; 48 pintc_regs->mask1 = 0x0; 49 pintc_regs->pending1 = 0xffffffff; 50 51 pintc_regs->enable2 = 0x0; 52 pintc_regs->mask2 = 0x0; 53 pintc_regs->pending2 = 0xffffffff; 54 return OK; 55 } 56 57 /* 58 ********************************************************************************************************* 59 * INTERRUPT EXIT 60 * 61 * Description: exit interrupt. 62 * 63 * Arguments : none. 64 * 65 * Returns : OK if exit succeeded, others if failed. 66 * 67 * Note : 68 ********************************************************************************************************* 69 */ intc_exit(void)70s32 intc_exit(void) 71 { 72 pintc_regs = NULL; 73 74 return OK; 75 } 76 77 /* 78 ********************************************************************************************************* 79 * ENABLE INTERRUPT 80 * 81 * Description: enable a specific interrupt. 82 * 83 * Arguments : intno : the source number of interrupt to which we want to enable. 84 * 85 * Returns : OK if enable interrupt succeeded, others if failed. 86 * 87 * Note : 88 ********************************************************************************************************* 89 */ intc_enable_interrupt(u32 intno)90s32 intc_enable_interrupt(u32 intno) 91 { 92 /*intno can't beyond then IRQ_SOURCE_MAX */ 93 /* ASSERT(intno < IRQ_SOUCE_MAX); */ 94 95 /* 96 * NMI interrupt should clear before enable. 97 * by sunny at 2012-6-12 19:30:22. 98 */ 99 if (intno == SUNXI_RINTC_IRQ_NMI) { 100 pintc_regs->pending = (1 << intno); 101 } 102 103 /*enable interrupt which number is intno */ 104 if (intno <= 31) 105 pintc_regs->enable |= (1 << intno); 106 else if (intno > 31 && intno <= 63) 107 pintc_regs->enable1 |= (1 << (intno - 32)); 108 else 109 pintc_regs->enable2 |= (1 << (intno - 64)); 110 111 return OK; 112 } 113 114 /* 115 ********************************************************************************************************* 116 * DISABLE INTERRUPT 117 * 118 * Description: disable a specific interrupt. 119 * 120 * Arguments : intno : the source number of interrupt which we want to disable. 121 * 122 * Returns : OK if disable interrupt succeeded, others if failed. 123 * 124 * Note : 125 ********************************************************************************************************* 126 */ intc_disable_interrupt(u32 intno)127s32 intc_disable_interrupt(u32 intno) 128 { 129 /*intno can't beyond then IRQ_SOURCE_MAX */ 130 /* ASSERT(intno < IRQ_SOUCE_MAX); */ 131 132 /*enable interrupt which number is intno */ 133 if (intno <= 31) 134 pintc_regs->enable &= ~(1 << intno); 135 else if (intno > 31 && intno <= 63) 136 pintc_regs->enable1 &= ~(1 << (intno - 32)); 137 else 138 pintc_regs->enable2 &= ~(1 << (intno - 64)); 139 140 return OK; 141 } 142 143 /* 144 ********************************************************************************************************* 145 * GET CURRENT INTERRUPT 146 * 147 * Description: get the source number of current interrupt. 148 * 149 * Arguments : none. 150 * 151 * Returns : the source number of current interrupt. 152 * 153 * Note : 154 ********************************************************************************************************* 155 */ intc_get_current_interrupt(void)156u32 intc_get_current_interrupt(void) 157 { 158 volatile u32 interrupt; 159 160 interrupt = (u32) ((pintc_regs->vector) >> 2); 161 162 return interrupt; 163 } 164 intc_set_mask(u32 intno,u32 mask)165s32 intc_set_mask(u32 intno, u32 mask) 166 { 167 /* intno can't beyond then IRQ_SOURCE_MAX */ 168 /* ASSERT(intno < IRQ_SOUCE_MAX); */ 169 170 /* enable interrupt which number is intno */ 171 if (intno <= 31) { 172 pintc_regs->mask &= ~(1 << intno); 173 pintc_regs->mask |= (mask << intno); 174 } else if (intno > 31 && intno <= 63) { 175 pintc_regs->mask1 &= ~(1 << (intno - 32)); 176 pintc_regs->mask1 |= (mask << intno); 177 } else { 178 pintc_regs->mask2 &= ~(1 << (intno - 64)); 179 pintc_regs->mask2 |= (mask << intno); 180 } 181 182 return OK; 183 } 184 intc_set_group_config(u32 grp_irq_num,u32 mask)185s32 intc_set_group_config(u32 grp_irq_num, u32 mask) 186 { 187 if (grp_irq_num <= 31) { 188 pintc_regs->group_config0 &= ~(1 << grp_irq_num); 189 pintc_regs->group_config0 |= (mask << grp_irq_num); 190 } else if (grp_irq_num > 31 && grp_irq_num <= 63) { 191 pintc_regs->group_config1 &= ~(1 << (grp_irq_num - 32)); 192 pintc_regs->group_config1 |= (mask << grp_irq_num); 193 } else if (grp_irq_num > 63 && grp_irq_num <= 95) { 194 pintc_regs->group_config2 &= ~(1 << (grp_irq_num - 64)); 195 pintc_regs->group_config2 |= (mask << grp_irq_num); 196 } else { 197 pintc_regs->group_config3 &= ~(1 << (grp_irq_num - 64)); 198 pintc_regs->group_config3 |= (mask << grp_irq_num); 199 } 200 201 return OK; 202 } 203