omap3530/assp/src/interrupts.cpp
changeset 0 6663340f3fc9
equal deleted inserted replaced
-1:000000000000 0:6663340f3fc9
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // omap3530/assp/src/interrupts.cpp
       
    15 // Template ASSP interrupt control and dispatch
       
    16 //
       
    17 
       
    18 #include <assp/omap3530_assp/omap3530_assp_priv.h>
       
    19 #include <assp/omap3530_assp/omap3530_irqmap.h>
       
    20 #include <assp/omap3530_assp/locks.h>
       
    21 
       
    22 SInterruptHandler Omap3530Interrupt::Handlers[KNumOmap3530Ints];
       
    23 MInterruptDispatcher*	TheDispatchers[ KIrqRangeCount ];
       
    24 
       
    25 #define OMAP3530_INTERRUPTS_INC
       
    26 
       
    27 #ifndef OMAP3530_INTERRUPTS_INC
       
    28 //TODO: Implement the asm IRQ & FIQ dispatcher
       
    29 #include "interrupts.cia"
       
    30 
       
    31 #else
       
    32 
       
    33 void IrqDispatch()
       
    34 {
       
    35 	CHECK_PRECONDITIONS( MASK_INTERRUPTS_DISABLED  ,Kern::Fault("IRQS ENABLED While reading IVT",__FILE__)); 
       
    36 	
       
    37 	TUint irqVector  =  AsspRegister::Read32(INTCPS_SIR_IRQ) &INTCPS_PENDING_MASK;
       
    38 	
       
    39 	TUint irqFlags = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock);
       
    40 	SInterruptHandler handler = Omap3530Interrupt::Handlers[irqVector];
       
    41 	__SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irqFlags);
       
    42 	
       
    43 	//may be useful in the interim but dont want a print in every dispatch
       
    44 	//__KTRACE_OPT(KHARDWARE,Kern::Printf("IRQDISPATCH V %x isr %x ptr %x",irqVector,handler.iIsr,handler.iPtr));
       
    45 	//execute handler now
       
    46 	((TIsr)*handler.iIsr)(handler.iPtr);
       
    47 
       
    48 	AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR);
       
    49 }
       
    50 
       
    51 void FiqDispatch()
       
    52 {
       
    53 	Omap3530Interrupt::Spurious((TAny*)KErrNotFound);
       
    54 }
       
    55 
       
    56 #endif
       
    57 
       
    58 #ifndef _DEBUG
       
    59 
       
    60 void Omap3530Interrupt::dumpINTCState(){}
       
    61 void Omap3530Interrupt::dumpIVTState(){}
       
    62 void TestHandler(TAny * wibble){}
       
    63 EXPORT_C void TestInterrupts(TInt id,TIsr func){}
       
    64 void TestExternalInterrupts(){}
       
    65 EXPORT_C void ClearAndDisableTestInterrupt(TInt anId){}
       
    66 void TestPriorities(){}
       
    67 #else
       
    68 
       
    69 void Omap3530Interrupt::dumpINTCState()
       
    70 {
       
    71 	Kern::Printf("INTCPS_SYSCONFIG %x",AsspRegister::Read32(INTCPS_SYSCONFIG));
       
    72 	Kern::Printf("INTCPS_SYSSTATUS %x",AsspRegister::Read32(INTCPS_SYSSTATUS));
       
    73 	Kern::Printf("INTCPS_SIR_IRQ %x",AsspRegister::Read32(INTCPS_SIR_IRQ));
       
    74 	Kern::Printf("INTCPS_SIR_FIQ %x",AsspRegister::Read32(INTCPS_SIR_FIQ));
       
    75 	Kern::Printf("INTCPS_CONTROL %x",AsspRegister::Read32(INTCPS_CONTROL));
       
    76 	Kern::Printf("INTCPS_PROTECTION %x",AsspRegister::Read32(INTCPS_PROTECTION));
       
    77 	Kern::Printf("INTCPS_IDLE %x",AsspRegister::Read32(INTCPS_IDLE));
       
    78 	Kern::Printf("INTCPS_IRQ_PRIORITY %x",AsspRegister::Read32(INTCPS_IRQ_PRIORITY));
       
    79 	Kern::Printf("INTCPS_FIQ_PRIORITY %x",AsspRegister::Read32(INTCPS_FIQ_PRIORITY));
       
    80 	Kern::Printf("INTCPS_THRESHOLD %x",AsspRegister::Read32(INTCPS_THRESHOLD));
       
    81 	Kern::Printf("INTCPS_ITR0 %x",AsspRegister::Read32(INTCPS_ITR(0)));
       
    82 	Kern::Printf("INTCPS_ITR1 %x",AsspRegister::Read32(INTCPS_ITR(1)));
       
    83 	Kern::Printf("INTCPS_ITR 2%x",AsspRegister::Read32(INTCPS_ITR(2)));
       
    84 	Kern::Printf("INTCPS_MIR0 %x",AsspRegister::Read32(INTCPS_MIRn(0)));
       
    85 	Kern::Printf("INTCPS_MIR1 %x",AsspRegister::Read32(INTCPS_MIRn(1)));
       
    86 	Kern::Printf("INTCPS_MIR2 %x",AsspRegister::Read32(INTCPS_MIRn(2)));
       
    87 	Kern::Printf("INTCPS_PENDING_IRQ0 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(0)));
       
    88 	Kern::Printf("INTCPS_PENDING_IRQ1 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(1)));
       
    89 	Kern::Printf("INTCPS_PENDING_IRQ2 %x",AsspRegister::Read32(INTCPS_PENDING_IRQ(2)));
       
    90 	Kern::Printf("INTCPS_PENDING_FIQ1 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(0)));
       
    91 	Kern::Printf("INTCPS_PENDING_FIQ0 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(1)));
       
    92 	Kern::Printf("INTCPS_PENDING_FIQ2 %x",AsspRegister::Read32(INTCPS_PENDING_FIQ(2)));
       
    93 	Kern::Printf("INTCPS_ILR0 %x",AsspRegister::Read32(INTCPS_ILRM(0)));
       
    94 	Kern::Printf("INTCPS_ILR1 %x",AsspRegister::Read32(INTCPS_ILRM(1)));
       
    95 	Kern::Printf("INTCPS_ILR2 %x",AsspRegister::Read32(INTCPS_ILRM(2)));
       
    96 	Kern::Printf("INTCPS_ISRSET0 %x", AsspRegister::Read32(INTCPS_ISRSET(0)));
       
    97 	Kern::Printf("INTCPS_ISRSET1 %x", AsspRegister::Read32(INTCPS_ISRSET(1)));
       
    98 	Kern::Printf("INTCPS_ISRSET2 %x", AsspRegister::Read32(INTCPS_ISRSET(2)));
       
    99 }
       
   100 
       
   101 
       
   102 void Omap3530Interrupt::dumpIVTState()
       
   103 {
       
   104 	//NOTE NOT THREAD SAFE ! 
       
   105 	TInt reg;
       
   106 	TInt bit;
       
   107 	
       
   108 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Omap3530Interrupt::dumpIVTState"));
       
   109 	
       
   110 	for(TInt i=0;i<KNumOmap3530Ints;i++)
       
   111 	{
       
   112 		GetRegisterAndBitOffset(i,reg,bit);
       
   113 		TUint val = AsspRegister::Read32(INTCPS_MIRn(reg));
       
   114 		TUint priVal = AsspRegister::Read32(INTCPS_ILRM(i));
       
   115 		val &= (0x1 << bit ); 
       
   116 		
       
   117 		Kern::Printf("INT_VECT %d F %x P %x MASK %d PRIORITY %d",i,Handlers[i].iIsr,Handlers[i].iPtr,(val >> bit),priVal >> 2);
       
   118 	}	
       
   119 }
       
   120 
       
   121 void TestHandler(TAny * wibble)
       
   122 {
       
   123 	TInt irq = (TInt)wibble;
       
   124 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler IN IRQ %d",irq));
       
   125 	Omap3530Interrupt::dumpINTCState();
       
   126 	ClearAndDisableTestInterrupt(irq);
       
   127 	Omap3530Interrupt::dumpINTCState();
       
   128 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler Interrupts OK ",irq));
       
   129 }
       
   130 
       
   131 
       
   132 
       
   133 void TestPriHandler(TAny * wibble)
       
   134 {
       
   135 	TInt irq = (TInt)wibble;
       
   136 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler PRI IN IRQ %d",irq));
       
   137 	Omap3530Interrupt::dumpINTCState();
       
   138 	ClearAndDisableTestInterrupt(irq);
       
   139 	Omap3530Interrupt::dumpINTCState();
       
   140 	
       
   141 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TestHandler Interrupts OK ",irq));
       
   142 }
       
   143 
       
   144 
       
   145 EXPORT_C void ClearAndDisableTestInterrupt(TInt anId)
       
   146 {
       
   147 	TInt reg,bit;
       
   148 	TInt irq = (TInt)anId;
       
   149 	__KTRACE_OPT(KHARDWARE,Kern::Printf("ClearAndDisableTestInterrupt IN IRQ %d",irq));
       
   150 	
       
   151 	Omap3530Interrupt::GetRegisterAndBitOffset(irq,reg,bit);
       
   152 	
       
   153 	AsspRegister::Write32(INTCPS_ISR_CLEAR(reg),1 << bit);
       
   154 	
       
   155 	Interrupt::Clear(irq);
       
   156 	
       
   157 	Interrupt::Disable(irq);
       
   158 	
       
   159 	Interrupt::Unbind(irq);
       
   160 
       
   161 	
       
   162 	
       
   163 }
       
   164 
       
   165 void TestPriorities()
       
   166 {
       
   167 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Priorities"));
       
   168 	Interrupt::Bind(EOmap3530_IRQ4_MCBSP2_ST_IRQ,TestPriHandler,(TAny*)EOmap3530_IRQ4_MCBSP2_ST_IRQ);
       
   169 	Interrupt::Bind(EOmap3530_IRQ5_MCBSP3_ST_IRQ,TestPriHandler,(TAny*)EOmap3530_IRQ5_MCBSP3_ST_IRQ);
       
   170 	
       
   171 	
       
   172 	TInt r = Interrupt::SetPriority(EOmap3530_IRQ4_MCBSP2_ST_IRQ,0);
       
   173 	if(r != KErrNone)
       
   174 	{
       
   175 		__KTRACE_OPT(KHARDWARE,Kern::Printf("%s SP1 r %d ",__FUNCTION__,r));
       
   176 	}
       
   177 			
       
   178 	r = Interrupt::SetPriority(EOmap3530_IRQ5_MCBSP3_ST_IRQ,0);
       
   179 	if(r != KErrNone)
       
   180 	{
       
   181 		__KTRACE_OPT(KHARDWARE,Kern::Printf("%s SP2 r %d ",__FUNCTION__,r));
       
   182 	}
       
   183 	
       
   184 	Omap3530Interrupt::dumpINTCState();
       
   185 	
       
   186 	Interrupt::Enable(EOmap3530_IRQ4_MCBSP2_ST_IRQ);
       
   187 	Interrupt::Enable(EOmap3530_IRQ5_MCBSP3_ST_IRQ);
       
   188 	
       
   189 	
       
   190 	Omap3530Interrupt::dumpIVTState();
       
   191 	TInt reg,bit,bit1;
       
   192 	Omap3530Interrupt::GetRegisterAndBitOffset(EOmap3530_IRQ5_MCBSP3_ST_IRQ,reg,bit);
       
   193 	Omap3530Interrupt::GetRegisterAndBitOffset(EOmap3530_IRQ4_MCBSP2_ST_IRQ,reg,bit1);
       
   194 	
       
   195 	AsspRegister::Write32(INTCPS_ISRSET(reg),((1 << bit) | ( 1 << bit1)));
       
   196 }
       
   197 
       
   198 EXPORT_C void TestInterrupts(TInt id,TIsr func)
       
   199 {
       
   200 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TestInterrupts"));
       
   201 	Interrupt::Bind(id,func,(TAny*)id);
       
   202 	
       
   203 	Omap3530Interrupt::dumpIVTState();
       
   204 	
       
   205 	Interrupt::Enable(id);
       
   206 	Omap3530Interrupt::dumpIVTState();
       
   207 	
       
   208 	TInt reg,bit;
       
   209 	Omap3530Interrupt::GetRegisterAndBitOffset(id,reg,bit);
       
   210 	
       
   211 	AsspRegister::Write32(INTCPS_ISRSET(reg),1 << bit);
       
   212 	Omap3530Interrupt::dumpINTCState();
       
   213 }
       
   214 
       
   215 
       
   216 
       
   217 #endif
       
   218 
       
   219 
       
   220 void Omap3530Interrupt::DisableAndClearAll()
       
   221 {
       
   222 	// Disable then clear all Hardware Interrupt sources
       
   223 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll 0 %x 1 %x 2 %x",
       
   224 			INTCPS_MIR_SETn(0),
       
   225 			INTCPS_MIR_SETn(1),
       
   226 			INTCPS_MIR_SETn(2)));
       
   227 	
       
   228 	//first we mask all vectors
       
   229 	AsspRegister::Write32(INTCPS_MIR_SETn(0),INTCPS_MIR_ALL_SET);
       
   230 	AsspRegister::Write32(INTCPS_MIR_SETn(1),INTCPS_MIR_ALL_SET);
       
   231 	AsspRegister::Write32(INTCPS_MIR_SETn(2),INTCPS_MIR_ALL_SET);
       
   232 
       
   233 	AsspRegister::Write32(INTCPS_ISR_CLEAR(0),0xffffffff);
       
   234 	AsspRegister::Write32(INTCPS_ISR_CLEAR(1),0xffffffff);
       
   235 	AsspRegister::Write32(INTCPS_ISR_CLEAR(2),0xffffffff);
       
   236 	
       
   237 	
       
   238 	AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR|INTCPS_CONTROL_FIQ_CLEAR); 
       
   239 		
       
   240 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll INTCPS_SIR_IRQ %x at %x",AsspRegister::Read32(INTCPS_SIR_IRQ),INTCPS_BASE ));
       
   241 	
       
   242 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::DisableAndClearAll OUT"));
       
   243 }
       
   244 
       
   245 void Omap3530Interrupt::Init1()
       
   246 {
       
   247 	
       
   248 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::Init1()"));
       
   249 	
       
   250 	//make sure everything is off first
       
   251 	
       
   252 	DisableAndClearAll();
       
   253 	
       
   254 	//Initialise the IVT to the spurious handler
       
   255 	//interrupts are not enabled yet but take mutex on the IVT anyway
       
   256 	
       
   257 	TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530IVTLock);
       
   258 	for (TInt i=0; i<KNumOmap3530Ints; i++)
       
   259 	{
       
   260 		Handlers[i].iPtr=(TAny*)i;
       
   261 		Handlers[i].iIsr=Spurious;
       
   262 	} 
       
   263 	__SPIN_UNLOCK_IRQRESTORE_W(Omap3530IVTLock,irq);
       
   264 	
       
   265 
       
   266 	Arm::SetIrqHandler((TLinAddr)IrqDispatch);
       
   267 	Arm::SetFiqHandler((TLinAddr)FiqDispatch);
       
   268 	
       
   269 	
       
   270 	//set the low power mode
       
   271 	//TODO: these registers are outside the mapped addressable ranged - and may be reserved as according to 
       
   272 	// part of the TRM.  So we will omit for now.
       
   273 	//AsspRegister::Write32(INTC_INIT_REGISTER1,INTCPS_INIT_RG_LOW_PWR);
       
   274 	//AsspRegister::Write32(INTC_INIT_REGISTER2,INTCPS_INIT_RG_LOW_PWR);
       
   275 		
       
   276 	//enable the clock sources ?
       
   277 	
       
   278 	//program the INTC to initial state.
       
   279 	AsspRegister::Write32(INTCPS_SYSCONFIG,INTCPS_SYSCONFIG_AUTOIDLE);
       
   280 	AsspRegister::Write32(INTCPS_IDLE,INTCPS_IDLE_TURBO);
       
   281 	
       
   282 	//TODO do we really want flat priorities ? 
       
   283 	for(TInt i=0;i<KNumOmap3530Ints;i++)
       
   284 	{
       
   285 		AsspRegister::Write32(INTCPS_ILRM(i), (INTCPS_ILRM_ROUTE_IRQ | (KOmap3530DefIntPriority <<2) ));
       
   286 	}
       
   287 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::Init1() OUT "));
       
   288 
       
   289 }
       
   290 
       
   291 void Omap3530Interrupt::Init3()
       
   292 	{
       
   293 
       
   294 	__KTRACE_OPT(KBOOT,Kern::Printf("Omap3530Interrupt::Init3"));
       
   295 		
       
   296 	}
       
   297 
       
   298 void Omap3530Interrupt::Spurious(TAny* anId)
       
   299 {
       
   300 	// handle an unexpected interrupt
       
   301 	dumpIVTState();
       
   302 	Kern::Fault("Omap3530Interrupt::Spurious",(TInt)anId);
       
   303 }
       
   304 
       
   305 EXPORT_C TInt Omap3530Interrupt::IsInterruptEnabled(TInt anId)
       
   306 	{
       
   307 	TInt isrBitOffset=0;
       
   308 	TInt reg=0;
       
   309 	Omap3530Interrupt::GetRegisterAndBitOffset(anId,reg,isrBitOffset);
       
   310 				
       
   311 	TUint val = AsspRegister::Read32(INTCPS_MIRn(reg));
       
   312 	val &=  (~(0x1 << isrBitOffset )); 
       
   313 	return (val & 0x1 << isrBitOffset) ?
       
   314 		1:
       
   315 	 	0;
       
   316 	}
       
   317 
       
   318 TInt Omap3530Interrupt::GetRegisterAndBitOffset(TInt anId,TInt &aReg,TInt &aOffset)
       
   319 {
       
   320 	if ((TUint)anId >= (TUint)KNumOmap3530Ints)
       
   321 	{
       
   322 		return KErrArgument;
       
   323 	}
       
   324 	else
       
   325 	{
       
   326 		aOffset  = (anId % 32);		
       
   327 		aReg = (anId  / 32);
       
   328 	}
       
   329 	return KErrNone;
       
   330 	
       
   331 }
       
   332 //
       
   333 // The APIs below assume ther is a second level Interrupt controller located at Omap3530Assp::Variant level which handles
       
   334 // interrupts generated by hardware at that level.
       
   335 //
       
   336 
       
   337 EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr)
       
   338 	{
       
   339 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind id=%d func=%08x ptr=%08x Var %x",aId,aIsr,aPtr,Omap3530Assp::Omap3530Assp::Variant));
       
   340 	TInt r;
       
   341 	// if ID indicates a chained interrupt, call Omap3530Assp::Variant...	
       
   342 
       
   343 	TInt index = aId >> KIrqRangeIndexShift;
       
   344 	if( index == 0 )
       
   345 		{
       
   346 		 if ((TUint)aId >= (TUint)KNumOmap3530Ints)
       
   347 			{
       
   348 			__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind id OOB %d MAX %d",aId,KNumOmap3530Ints)); 
       
   349 			r = KErrArgument;
       
   350 			}
       
   351 		else
       
   352 			{
       
   353 			TUint irq = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock);
       
   354 			SInterruptHandler& h=Omap3530Interrupt::Handlers[aId];
       
   355 			
       
   356 			if (h.iIsr != Omap3530Interrupt::Spurious)
       
   357 				{
       
   358 				r=KErrInUse;
       
   359 				__SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq);
       
   360 				__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind Cant Bind irq (IN_USE %d",aId));
       
   361 				}
       
   362 			else
       
   363 				{	
       
   364 				__SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq);
       
   365 				TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530IVTLock);
       
   366 				h.iPtr=aPtr;
       
   367 				h.iIsr=aIsr;
       
   368 				__SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530IVTLock,irq);
       
   369 				__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind BOUND %d",aId));
       
   370 				r = KErrNone;
       
   371 				}
       
   372 			__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind OUT"));
       
   373 			}
       
   374 		}
       
   375 	else if( index > 0 )
       
   376 		{
       
   377 		r = TheDispatchers[ index ]->Bind( aId, aIsr, aPtr );
       
   378 		}
       
   379 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   380 		{
       
   381 		__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind extint %d",aId));
       
   382 		return Omap3530Assp::Variant->InterruptBind(aId,aIsr,aPtr);
       
   383 		}
       
   384 	else
       
   385 		{
       
   386 		r = KErrArgument;
       
   387 		}
       
   388 	
       
   389 	return r;
       
   390 	}
       
   391 
       
   392 EXPORT_C TInt Interrupt::Unbind(TInt aId)
       
   393 	{
       
   394 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind id=%d",aId));
       
   395 	TInt r;
       
   396 	TInt index = aId >> KIrqRangeIndexShift;
       
   397 
       
   398 	if( index == 0 )
       
   399 		{
       
   400 		if ((TUint)aId >= (TUint)KNumOmap3530Ints)
       
   401 			{
       
   402 			r=KErrArgument;
       
   403 			}
       
   404 		else	
       
   405 			{
       
   406 			TUint irq = __SPIN_LOCK_IRQSAVE_R(Omap3530IVTLock);
       
   407 			SInterruptHandler& h=Omap3530Interrupt::Handlers[aId];
       
   408 			__SPIN_UNLOCK_IRQRESTORE_R(Omap3530IVTLock,irq);
       
   409 			
       
   410 			if (h.iIsr == Omap3530Interrupt::Spurious)
       
   411 				{
       
   412 				r=KErrGeneral;
       
   413 				}
       
   414 			else
       
   415 				{
       
   416 				TInt isrBitOffset=0;
       
   417 				TInt reg=0;
       
   418 				Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset);
       
   419 #ifdef _DEBUG
       
   420 				TUint val = AsspRegister::Read32(INTCPS_MIRn(reg));	 
       
   421 				if( ! (val & (0x1 << isrBitOffset)))
       
   422 					{
       
   423 					__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind THIS IRQ IS STILL ENABLED - update your code"));
       
   424 					}
       
   425 				
       
   426 				TUint irqVector  =  AsspRegister::Read32(INTCPS_SIR_IRQ) &INTCPS_PENDING_MASK;
       
   427 				if(irqVector == aId  )
       
   428 					{		
       
   429 					__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind THIS IRQ IS STILL PENDING - update your code"));
       
   430 					}
       
   431 #endif			
       
   432 				TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530INTCLock);
       
   433 				h.iPtr=(TAny*)aId;
       
   434 				h.iIsr=Omap3530Interrupt::Spurious;
       
   435 				__SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530INTCLock,irq);
       
   436 					
       
   437 				//calculate the register and bit offset for this id
       
   438 				//and disable the corresponding Hardware Interrupt source
       
   439 				
       
   440 				AsspRegister::Write32(INTCPS_MIR_SETn(reg),(1 << isrBitOffset));			
       
   441 				r = KErrNone;
       
   442 				}
       
   443 			}
       
   444 		}
       
   445 	else if( index > 0 )
       
   446 		{
       
   447 		r = TheDispatchers[ index ]->Unbind( aId );
       
   448 		}
       
   449 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   450 		{
       
   451 		r = Omap3530Assp::Variant->InterruptUnbind(aId);
       
   452 		}
       
   453 	else
       
   454 		{
       
   455 		r = KErrArgument;
       
   456 		}
       
   457 
       
   458 	return r;
       
   459 	}
       
   460 
       
   461 EXPORT_C TInt Interrupt::Enable(TInt aId)
       
   462 {
       
   463 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Enable id=%d",aId));
       
   464 	TInt r;
       
   465 	TInt index = aId >> KIrqRangeIndexShift;
       
   466 
       
   467 	if( index == 0 )
       
   468 		{
       
   469 		if ((TUint)aId>=(TUint)KNumOmap3530Ints)
       
   470 			{	
       
   471 			r=KErrArgument;
       
   472 			}
       
   473 		else if (Omap3530Interrupt::Handlers[aId].iIsr==Omap3530Interrupt::Spurious)
       
   474 			{
       
   475 			r=KErrNotReady;
       
   476 			}
       
   477 		else
       
   478 			{
       
   479 			__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Enable %d",aId));
       
   480 			// Enable the corresponding Hardware Interrupt source
       
   481 			TInt isrBitOffset=0;
       
   482 			TInt reg=0;
       
   483 			Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset);
       
   484 			AsspRegister::Write32(INTCPS_MIR_CLEARn(reg),(1 << isrBitOffset));
       
   485 			r = KErrNone;
       
   486 			}		
       
   487 		}
       
   488 	else if( index > 0 )
       
   489 		{
       
   490 		r = TheDispatchers[ index ]->Enable( aId );
       
   491 		}
       
   492 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   493 		{
       
   494 		r = Omap3530Assp::Variant->InterruptEnable(aId);
       
   495 		}
       
   496 	else 
       
   497 		{
       
   498 		r = KErrArgument;
       
   499 		}
       
   500 	return r;
       
   501 	}
       
   502 
       
   503 EXPORT_C TInt Interrupt::Disable(TInt aId)
       
   504 {
       
   505 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Disable id=%d",aId));
       
   506 	TInt r;
       
   507 	TInt index = aId >> KIrqRangeIndexShift;
       
   508 
       
   509 	if( index == 0 )
       
   510 		{
       
   511 		if ((TUint)aId >= (TUint)KNumOmap3530Ints)
       
   512 			{
       
   513 			r=KErrArgument;
       
   514 			}
       
   515 		else
       
   516 			{	
       
   517 			// Disable the corresponding Hardware Interrupt source
       
   518 			TInt isrBitOffset=0;
       
   519 			TInt reg=0;
       
   520 			Omap3530Interrupt::GetRegisterAndBitOffset(aId,reg,isrBitOffset);
       
   521 			AsspRegister::Write32(INTCPS_MIR_SETn(reg),(1 << isrBitOffset));
       
   522 			r = KErrNone;
       
   523 			}
       
   524 		}
       
   525 	else if( index > 0 )
       
   526 		{
       
   527 		r = TheDispatchers[ index ]->Disable( aId );
       
   528 		}
       
   529 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   530 		{
       
   531 		r = Omap3530Assp::Variant->InterruptDisable(aId);
       
   532 		}
       
   533 	else
       
   534 		{
       
   535 		r = KErrArgument;
       
   536 		}
       
   537 
       
   538 	return r;
       
   539 	}
       
   540 
       
   541 EXPORT_C TInt Interrupt::Clear(TInt aId)
       
   542 	{
       
   543 	//__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Clear id=%d",aId));
       
   544 	TInt r = KErrUnknown;
       
   545 	TInt index = aId >> KIrqRangeIndexShift;
       
   546 
       
   547 	if( index == 0 )
       
   548 		{
       
   549 		if ((TUint)aId >= (TUint)KNumOmap3530Ints)
       
   550 			{
       
   551 			r=KErrArgument;
       
   552 			}
       
   553 		else
       
   554 			{
       
   555 			TInt curVector = AsspRegister::Read32(INTCPS_SIR_IRQ);
       
   556 			// Clear the corresponding Hardware Interrupt source
       
   557 			if(curVector == aId)
       
   558 				{
       
   559 				//TODO:  determine whether we are dealing with a FIQ or IRQ source
       
   560 				// for now assuming all are IRQS
       
   561 				//__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Clear id=%d x %x",aId,curVector ));
       
   562 				AsspRegister::Write32(INTCPS_CONTROL,INTCPS_CONTROL_IRQ_CLEAR);
       
   563 				}
       
   564 			}
       
   565 		}
       
   566 	else if( index > 0 )
       
   567 		{
       
   568 		r = TheDispatchers[ index ]->Clear( aId );
       
   569 		}
       
   570 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   571 		{
       
   572 		r = Omap3530Assp::Variant->InterruptClear(aId);
       
   573 		}
       
   574 	else
       
   575 		{
       
   576 		r = KErrArgument;
       
   577 		}
       
   578 
       
   579 	return r;
       
   580 	}
       
   581 
       
   582 EXPORT_C TInt Interrupt::SetPriority(TInt aId, TInt aPriority)
       
   583 	{
       
   584 	// If Interrupt priorities are supported the dispatchers need to take this in consideration
       
   585 	
       
   586 	// (IrqDispatch/FiqDispatch)
       
   587 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::SetPriority id=%d pri=%d",aId,aPriority));
       
   588 	
       
   589 	TInt r;
       
   590 	TInt index = aId >> KIrqRangeIndexShift;
       
   591 	
       
   592 	if( index == 0 )
       
   593 		{
       
   594 		if ((TUint)aId >= (TUint)KNumOmap3530Ints)
       
   595 			{
       
   596 			r = KErrArgument;
       
   597 			}
       
   598 		else
       
   599 			{
       
   600 			TUint irq = __SPIN_LOCK_IRQSAVE_W(Omap3530Interrupt::Omap3530INTCLock);
       
   601 			TUint curIRLMi = AsspRegister::Read32(INTCPS_ILRM(aId));
       
   602 			curIRLMi = ( curIRLMi & 0x000000003) |  (aPriority << 0x2) ; 
       
   603 			AsspRegister::Write32(INTCPS_ILRM(aId),curIRLMi);
       
   604 			__SPIN_UNLOCK_IRQRESTORE_W(Omap3530Interrupt::Omap3530INTCLock,irq);
       
   605 			r = KErrNone;
       
   606 			}
       
   607 		}
       
   608 	else if( index > 0 )
       
   609 		{
       
   610 		r = TheDispatchers[ index ]->SetPriority( aId, aPriority );
       
   611 		}
       
   612 	else if (Omap3530Assp::Variant->IsExternalInterrupt(aId))
       
   613 		{
       
   614 		r = KErrNotSupported;
       
   615 		}
       
   616 	else
       
   617 		{
       
   618 		r = KErrArgument;
       
   619 		}
       
   620 
       
   621 	return r;
       
   622 	}
       
   623 
       
   624 
       
   625 EXPORT_C void MInterruptDispatcher::Register( TIrqRangeIndex aIndex )
       
   626 	{
       
   627 	__ASSERT_ALWAYS( TheDispatchers[ aIndex ] == NULL, Kern::Fault( "interrupts.cpp", __LINE__ ) );
       
   628 	TheDispatchers[ aIndex ] = this;
       
   629 	}
       
   630