#include "irq.h" #define eLBC_CS_BUS_BASE 0xf8000000 #define eLBC_CS_BUS_WIDTH 0x2000000 #define IRQ_REGS_BASE (0xe0000700) #define IRQ_REGS_SIZE (0xc0) #define BUS_IRQ3_OFFSET (1<<28) // IRQ3 #define BUS_IRQ2_OFFSET (1<<29) // IRQ2 #define BUS_IRQ1_OFFSET (1<<30) // IRQ1 #define BUS_IRQ0_OFFSET (1<<31) // IRQ0 #define BUS_IRQ1_MODE (1 << 14) // low_to_high or high_to_low #define BUS_IRQ3_MODE (1 << 12) // low_to_high or high_to_low //#define _10MS_IRQ BUS_IRQ3_OFFSET #define USED_IRQ1 (0) #define USED_IRQ3 (1) extern const char* get_cmd_line_string(void); static E_TIMER_1MS e_timer_1ms; static u32 g_UsedIrq = USED_IRQ3; static u32 g_IrqTable[2][3] = { {BUS_IRQ1_OFFSET, BUS_IRQ1_MODE, 0xFFFFFFFF}, {BUS_IRQ3_OFFSET, BUS_IRQ3_MODE, 0xFFFFFFFF}, }; char* GetBoardName(void) { const char splt_char[] = " "; char buf[512]; char* s = buf; char* token; const char* source = get_cmd_line_string(); memset(buf, 0, 512); strlcpy(buf, source, strlen(source)); for(token = strsep(&s, splt_char); token != NULL; token = strsep(&s, splt_char)) { if(strlen(token) > 8) { char* pStr = strrchr(token, '#'); if(pStr != NULL) { if(strlen(pStr) > 1) { return (pStr + 1); } } } } return "Unknown"; } E_TIMER_1MS* irq_get_timer(void) { return &e_timer_1ms; } void handler_irq() { uint32_t* p; p = e_timer_1ms.pBase; p[IRQ_SEPNR] |= g_IrqTable[g_UsedIrq][0]; } int irq_init(void) { int ret = 0; uint32_t* p; struct device_node* np1, *np3; struct resource irq1, irq3; for_each_compatible_node(np1, NULL, "fsl,irq1") { ret = of_irq_to_resource(np1, 0, &irq1); g_IrqTable[USED_IRQ1][2] = irq1.start; } for_each_compatible_node(np3, NULL, "fsl,irq3") { ret = of_irq_to_resource(np3, 0, &irq3); g_IrqTable[USED_IRQ3][2] = irq3.start; } #if 0 if(strcmp(GetBoardName(), "MSB") == 0) { g_UsedIrq = USED_IRQ3; strcpy(e_timer_1ms.irqName, "IRQ3"); } else if(strcmp(GetBoardName(), "UMB") == 0) { g_UsedIrq = USED_IRQ1; strcpy(e_timer_1ms.irqName, "IRQ1"); } else if(strcmp(GetBoardName(), "SG") == 0) { g_UsedIrq = USED_IRQ1; strcpy(e_timer_1ms.irqName, "IRQ1"); } else { g_UsedIrq = USED_IRQ3; strcpy(e_timer_1ms.irqName, "IRQ3"); } #else if(strcmp(GetBoardName(), "SG") == 0) { g_UsedIrq = USED_IRQ1; strcpy(e_timer_1ms.irqName, "IRQ1"); } else { g_UsedIrq = USED_IRQ3; strcpy(e_timer_1ms.irqName, "IRQ3"); } #endif e_timer_1ms.irq = g_IrqTable[g_UsedIrq][2]; printk("Board %s timer interrupt %s no: %d, Offset: 0x%08X, Mode: 0x%08X\n", GetBoardName(), e_timer_1ms.irqName, e_timer_1ms.irq, g_IrqTable[g_UsedIrq][1], g_IrqTable[g_UsedIrq][0]); e_timer_1ms.pBase = ioremap(IRQ_REGS_BASE, IRQ_REGS_SIZE); p = e_timer_1ms.pBase; disable_irq(e_timer_1ms.irq); p[IRQ_SEPNR] |= g_IrqTable[g_UsedIrq][0]; // clear the irq flag p[IRQ_SECNR] |= g_IrqTable[g_UsedIrq][1]; // low_to_high or high_to_low p[IRQ_SEPCR] &= ~(g_IrqTable[g_UsedIrq][0]); // high_to_low p[IRQ_SEMSR] |= (g_IrqTable[g_UsedIrq][0]); // enable irq 1 printk("IRQ_SEPNR = 0x%08X, IRQ_SECNR = 0x%08X, IRQ_SEPCR = 0x%08X IRQ_SEMSR = 0x%08X IRQ_SEFCR = 0x%08X\n", p[IRQ_SEPNR], p[IRQ_SECNR], p[IRQ_SEPCR], p[IRQ_SEMSR], p[IRQ_SEFCR]); enable_irq(e_timer_1ms.irq); //cs_base = (void*)ioremap(eLBC_CS_BUS_BASE, eLBC_CS_BUS_WIDTH); return 0; } void irq_exit(void) { uint32_t* p; p = e_timer_1ms.pBase; mdelay(1); p[IRQ_SEMSR] &= ~(g_IrqTable[g_UsedIrq][0]); disable_irq(e_timer_1ms.irq); iounmap(p); // iounmap(cs_base); return; }