www.pudn.com > S3c2410bsp.zip > 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;
    }