/* ********************************************************************************************************* * LINUX-KERNEL * AllWinner Linux Platform Develop Kits * Kernel Module * * (c) Copyright 2006-2011, kevin.z China * All Rights Reserved * * File : mem_int.c * By : gq.yang * Version : v1.0 * Date : 2012-11-3 20:13 * Descript: interrupt for platform mem * Update : date auther ver notes ********************************************************************************************************* */ #include "pm_i.h" static void *GicDDisc; static void *GicCDisc; /* ********************************************************************************************************* * STANDBY INTERRUPT INITIALISE * * Description: mem interrupt initialise. * * Arguments : none. * * Returns : 0/-1; ********************************************************************************************************* */ __s32 mem_int_init(void) { __u32 i = 0; GicDDisc = (void *)IO_ADDRESS(SUNXI_GIC_DIST_PBASE); GicCDisc = (void *)IO_ADDRESS(SUNXI_GIC_CPU_PBASE); //printk("gic iar == 0x%x. \n", *(volatile __u32 *)(IO_ADDRESS(SUNXI_GIC_CPU_PBASE)+0x0c)); /* initialise interrupt enable and mask for mem */ /* * Disable all interrupts. Leave the PPI and SGIs alone * as these enables are banked registers. */ for (i = 4; i < (GIC_400_ENABLE_LEN); i += 4) *(volatile __u32 *)(GicDDisc + GIC_DIST_ENABLE_CLEAR + i) = 0xffffffff; /*config cpu interface*/ #if 0 *(volatile __u32 *)(GicCDisc + GIC_CPU_PRIMASK) = 0xf0; *(volatile __u32 *)(GicCDisc + GIC_CPU_CTRL) = 0x1; #endif #if 1 /* clear external irq pending: needed */ for (i = 4; i < (GIC_400_ENABLE_LEN); i += 4) *(volatile __u32 *)(GicDDisc + GIC_DIST_PENDING_CLEAR + i) = 0xffffffff; #endif //the print info just to check the pending state, actually, after u read iar, u need to access end of interrupt reg; i = *(volatile __u32 *)(GicCDisc + 0x0c); if(i != 0x3ff){ //u need to *(volatile __u32 *)(GicCDisc + 0x10) = i; printk("notice: gic iar == 0x%x. \n", i); } return 0; } /* ********************************************************************************************************* * STANDBY INTERRUPT INITIALISE * * Description: mem interrupt exit. * * Arguments : none. * * Returns : 0/-1; ********************************************************************************************************* */ __s32 mem_int_exit(void) { int i = 0; volatile __u32 enable_bit = 0; //all the disable-int-src pending, need to be clear for(i = 0; i < GIC_400_ENABLE_LEN; i += 4){ enable_bit = *(volatile __u32 *)(GicDDisc + GIC_DIST_ENABLE_SET + i); *(volatile __u32 *)(GicDDisc + GIC_DIST_PENDING_CLEAR + i) &= (~enable_bit); } return 0; } /* ********************************************************************************************************* * QUERY INTERRUPT * * Description: enable interrupt. * * Arguments : src interrupt source number. * * Returns : 0/-1; ********************************************************************************************************* */ __s32 mem_enable_int(enum interrupt_source_e src) { __u32 tmpGrp = (__u32)src >> 5; __u32 tmpSrc = (__u32)src & 0x1f; GicDDisc = (void *)IO_ADDRESS(SUNXI_GIC_DIST_PBASE); GicCDisc = (void *)IO_ADDRESS(SUNXI_GIC_CPU_PBASE); if(0 == src){ return -1; } //enable interrupt source *(volatile __u32 *)(GicDDisc + GIC_DIST_ENABLE_SET + tmpGrp*4) |= (1<> 5; __u32 tmpSrc = (__u32)src & 0x1f; GicDDisc = (void *)IO_ADDRESS(SUNXI_GIC_DIST_PBASE); GicCDisc = (void *)IO_ADDRESS(SUNXI_GIC_CPU_PBASE); if(0 == src){ return -1; } result = *(volatile __u32 *)(GicDDisc + GIC_DIST_PENDING_SET + tmpGrp*4) & (1<