www.pudn.com > S3c2410bsp.rar > s3c2410xIntrCtl.c
/* s3c2410xIntrCtl.c - Samsung KS32C interrupt controller driver */
#include "copyright_wrs.h"
#include "vxWorks.h"
#include "config.h"
#include "intLib.h"
#include "s3c2410x.h"
#if !defined (S3C2410X_INTPEND) || !defined (S3C2410X_INTENB) || \
!defined (S3C2410X_INTMASK_VAL) || !defined (S3C2410X_INTLEVEL_NUM) || \
!defined (S3C2410X_INTDIS)
# error missing S3C2410X interrupt definitions
#endif
IMPORT FUNCPTR sysIntLvlVecChkRtn;
IMPORT FUNCPTR sysIntLvlEnableRtn;
IMPORT FUNCPTR sysIntLvlDisableRtn;
#define S3C2410X_INT_VEC_BASE (0x0)
#ifndef S3C2410X_INT_REG_READ
# define S3C2410X_INT_REG_READ(x,result) \
((result) = *(volatile UINT32 *)(x))
#endif
#ifndef S3C2410X_INT_REG_WRITE
# define S3C2410X_INT_REG_WRITE(x,data) \
(*((volatile UINT32 *)(x)) = (data))
#endif
#ifndef S3C2410X_INT_LVL_VEC_MAP
# define S3C2410X_INT_LVL_VEC_MAP(level, vector) \
((vector) = ((level) + S3C2410X_INT_VEC_BASE))
#endif
#ifndef S3C2410X_INT_PEND_LVL_MAP
# define S3C2410X_INT_PEND_LVL_MAP(pendReg, level) \
((level) = (pendReg))
#endif
#define s3c2410x_INT_ALL_ENABLED (S3C2410X_INTLEVEL_NUM)
#define s3c2410x_INT_ALL_DISABLED (S3C2410X_INTLEVEL_NUM-1)
LOCAL UINT32 s3c2410xIntLvlEnabled;
STATUS s3c2410xIntLvlVecChk (int*, int*);
STATUS s3c2410xIntLvlEnable (int);
STATUS s3c2410xIntLvlDisable (int);
STATUS s3c44BIntLvlAck (int level, int vector)
{
S3C2410X_INT_REG_WRITE(S3C2410X_INTPEND,(1 << vector));
S3C2410X_INT_REG_WRITE(S3C2410X_SRCPND,(1 << vector));
return OK;
}
/*******************************************************************************
*
* s3c2410xIntDevInit - initialize the interrupt controller
*
*
*
* RETURNS: N/A
*/
void s3c2410xIntDevInit (void)
{
UINT32 tempUINT32 = 0;
S3C2410X_INT_REG_WRITE (S3C2410X_INTMASK,0xfeffffbf);
s3c2410x_INT_REG_WRITE(S3C2410X_INTSUBMSK,0x7ff);
s3c2410x_INT_REG_READ(S3C2410X_SUBSRCPND ,tempUINT32);
s3c2410x_INT_REG_WRITE(S3C2410X_SUBSRCPND,tempUINT32);
s3c2410x_INT_REG_READ(S3C2410X_SRCPND,tempUINT32);
s3c2410x_INT_REG_WRITE(S3C2410X_SRCPND,tempUINT32);
s3c2410x_INT_REG_READ(S3C2410X_INTPEND,tempUINT32);
s3c2410x_INT_REG_WRITE(S3C2410X_INTPEND,tempUINT32);
S3C2410X_INT_REG_WRITE (S3C2410X_INTMODE,S3C2410X_INTMODEIRQ);
S3C2410X_INT_REG_WRITE (S3C2410X_PRIORITY ,0x0);
S3C2410X_INT_REG_WRITE (S3C2410X_EXTINT0,0x11111111);
sysIntLvlVecChkRtn = s3c2410xIntLvlVecChk;
sysIntLvlEnableRtn = s3c2410xIntLvlEnable;
sysIntLvlDisableRtn = s3c2410xIntLvlDisable;
s3c2410xIntLvlEnabled = 0x0;
}
/*******************************************************************************
*
* s3c2410xIntLvlVecChk - check for and return any pending interrupts
*
*
* The return value ERROR indicates that no pending interrupt was found and
* that the level and vector values were not returned.
*
* RETURNS: OK or ERROR if no interrupt is pending.
*/
STATUS s3c2410xIntLvlVecChk
(
int* pLevel,
int* pVector
)
{
UINT32 newLevel;
UINT32 tempUINT32;
S3C2410X_INT_REG_READ (S3C2410X_INTPEND, newLevel);
if ((newLevel & S3C2410X_INTMASK_VAL) == 0)
return ERROR;
s3c2410x_INT_REG_READ(S3C2410X_INTOFFSET , tempUINT32);
if ((newLevel == 0) ||(tempUINT32>S3C2410X_INTLEVEL_NUM))
return ERROR;
*pVector = tempUINT32;
if((1<= S3C2410X_INTLEVEL_NUM)
return ERROR;
key = intLock ();
s3c2410xIntLvlEnabled |= ((1 << level));
S3C2410X_INT_REG_WRITE (S3C2410X_INTMASK,
((~s3c2410xIntLvlEnabled) & S3C2410X_INTMASK_VAL));
intUnlock (key);
return OK;
}
/*******************************************************************************
*
* s3c2410xIntLvlDisable - disable a single interrupt level
*
*
* RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
*/
STATUS s3c2410xIntLvlDisable
(
int level /* level to be disabled */
)
{
int key;
if (level < 0 ||
level >= S3C2410X_INTLEVEL_NUM)
return ERROR;
key = intLock ();
s3c2410xIntLvlEnabled &= ~(1 << level);
S3C2410X_INT_REG_WRITE (S3C2410X_INTMASK,
((~s3c2410xIntLvlEnabled) & S3C2410X_INTMASK_VAL));
intUnlock (key);
return OK;
}