174 lines
4.0 KiB
C
174 lines
4.0 KiB
C
|
#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;
|
||
|
}
|