+void interrupt_soft_enable(u8 src_number) {
+
+ VICSoftInt=(1<<src_number);
+}
+
+int interrupt_enable(u8 src_number,u8 mode,u8 prio,u32 callback_addr) {
+
+ u32 *addr;
+ u32 *cntl;
+
+ addr=(u32 *)&VICVectAddr0;
+ cntl=(u32 *)&VICVectCntl0;
+
+ /* check whether this ir source is allready assigned */
+ if(VICIntEnable&(1<<src_number))
+ return INTERRUPT_USED;
+
+ /* prepare depending on mode */
+ switch(mode) {
+ case INTERRUPT_MODE_FIQ:
+ VICIntSelect|=(1<<src_number);
+ break;
+ case INTERRUPT_MODE_VIRQ:
+ if(addr[prio]&0x3f)
+ return INTERRUPT_PRIORITY_USED;
+ *((volatile u32 *)(addr+prio))=callback_addr;
+ *((volatile u32 *)(cntl+prio))=(src_number&0x1f)+0x20;
+ case INTERRUPT_MODE_IRQ:
+ default:
+ break;
+ }
+
+ /* force interrupt */
+ VICIntEnable=(1<<src_number);
+
+ return INTERRUPT_SET;
+}
+
+int interrupt_change_callback(u8 src_number,u32 callback) {
+
+ int i;
+ u32 *addr,*cntl;
+
+ cntl=(u32 *)&VICVectCntl0;
+ addr=(u32 *)&VICVectAddr0;
+
+ i=0;
+ while(i<INTERRUPT_MAX_VIC) {
+ if((*cntl&0x1f)==src_number) {
+ *(addr+i)=callback;
+ return INTERRUPT_CALLBACK_CHANGED;
+ }
+ i++;
+ }
+
+ return INTERRUPT_SRC_NOT_USED;
+}