bsps/powerpc: Introduction of interrupt locks

Interrupt locks are introduced in shared vme device drivers to enable
compilation in an SMP configuration of the qoriq BSP.
This commit is contained in:
Vincenzo Calabretta
2024-05-07 18:26:28 +02:00
parent f5b52a3af0
commit 1f4e0c1036
2 changed files with 45 additions and 39 deletions

View File

@@ -545,16 +545,17 @@ vmeTsi148Reset(void)
vmeTsi148ResetXX(THEBASE);
}
RTEMS_INTERRUPT_LOCK_DEFINE( static, vmeTsi148_lock, "vmeTsi148_lock" )
void
vmeTsi148ResetBusXX(BERegister *base)
{
unsigned long flags;
uint32_t v;
rtems_interrupt_lock_context lock_context;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
v = TSI_RD(base, TSI_VCTRL_REG);
TSI_WR(base, TSI_VCTRL_REG, v | TSI_VCTRL_SRESET);
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
}
void
@@ -1410,7 +1411,8 @@ int
vmeTsi148IntRoute(unsigned int level, unsigned int pin)
{
int i;
unsigned long mask, shift, mapreg, flags, wire;
unsigned long mask, shift, mapreg, wire;
rtems_interrupt_lock_context lock_context;
if ( pin >= TSI_NUM_WIRES || ! tsi_wire[pin] || !vmeTsi148IrqMgrInstalled )
return -1;
@@ -1442,8 +1444,7 @@ unsigned long mask, shift, mapreg, flags, wire;
/* wires are offset by 1 so we can initialize the wire table to all zeros */
wire = (tsi_wire[pin]-1) << shift;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
for ( i = 0; i<TSI_NUM_WIRES; i++ ) {
wire_mask[i] &= ~mask;
}
@@ -1453,7 +1454,7 @@ rtems_interrupt_disable(flags);
mask |= wire;
TSI_WR( THEBASE, mapreg, mask );
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
return 0;
}
@@ -1461,9 +1462,9 @@ VmeTsi148ISR
vmeTsi148ISRGet(unsigned long vector, void **parg)
{
VmeTsi148ISR rval = 0;
unsigned long flags;
volatile IRQEntry *p;
int v = uni2tsivec(vector);
rtems_interrupt_lock_context lock_context;
if ( v < 0 )
@@ -1471,13 +1472,13 @@ int v = uni2tsivec(vector);
p = irqHdlTbl + v;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
if ( *p ) {
if ( parg )
*parg = (*p)->usrData;
rval = (*p)->isr;
}
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
return rval;
}
@@ -1794,8 +1795,8 @@ vmeTsi148InstallISR(unsigned long vector, VmeTsi148ISR hdl, void *arg)
{
IRQEntry ip;
int v;
unsigned long flags;
volatile IRQEntry *p;
rtems_interrupt_lock_context lock_context;
if ( !vmeTsi148IrqMgrInstalled || (v = uni2tsivec(vector)) < 0 )
return -1;
@@ -1808,14 +1809,14 @@ volatile IRQEntry *p;
ip->isr=hdl;
ip->usrData=arg;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
if (*p) {
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
free(ip);
return -1;
}
*p = ip;
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
return 0;
}
@@ -1824,22 +1825,22 @@ vmeTsi148RemoveISR(unsigned long vector, VmeTsi148ISR hdl, void *arg)
{
int v;
IRQEntry ip;
unsigned long flags;
volatile IRQEntry *p;
rtems_interrupt_lock_context lock_context;
if ( !vmeTsi148IrqMgrInstalled || (v = uni2tsivec(vector)) < 0 )
return -1;
p = irqHdlTbl + v;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
ip = *p;
if ( !ip || ip->isr!=hdl || ip->usrData!=arg ) {
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
return -1;
}
*p = 0;
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
free(ip);
return 0;
@@ -1849,8 +1850,9 @@ static int
intDoEnDis(unsigned int level, int dis)
{
BERegister *b = THEBASE;
unsigned long flags, v;
unsigned long v;
int shift;
rtems_interrupt_lock_context lock_context;
if ( ! vmeTsi148IrqMgrInstalled || (shift = lvl2bitno(level)) < 0 )
return -1;
@@ -1860,7 +1862,7 @@ int shift;
if ( !dis )
return (int)(v & TSI_RD(b, TSI_INTEO_REG) & TSI_RD(b, TSI_INTEN_REG)) ? 1 : 0;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
if ( dis<0 ) {
TSI_WR(b, TSI_INTEN_REG, TSI_RD(b, TSI_INTEN_REG) & ~v);
TSI_WR(b, TSI_INTEO_REG, TSI_RD(b, TSI_INTEO_REG) & ~v);
@@ -1868,7 +1870,7 @@ int shift;
TSI_WR(b, TSI_INTEN_REG, TSI_RD(b, TSI_INTEN_REG) | v);
TSI_WR(b, TSI_INTEO_REG, TSI_RD(b, TSI_INTEO_REG) | v);
}
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
return 0;
}

View File

@@ -1746,11 +1746,14 @@ int shift = -1;
return shift;
}
RTEMS_INTERRUPT_LOCK_DEFINE( static, vmeUniverse_lock, "vmeUniverse_lock" )
int
vmeUniverseIntRoute(unsigned int level, unsigned int pin)
{
int i, shift;
unsigned long mask, mapreg, flags, wire;
unsigned long mask, mapreg, wire;
rtems_interrupt_lock_context lock_context;
if ( pin >= UNIV_NUM_WIRES || ! universe_wire[pin] || !vmeUniverseIrqMgrInstalled )
return -1;
@@ -1779,7 +1782,7 @@ unsigned long mask, mapreg, flags, wire;
/* wires are offset by 1 so we can initialize the wire table to all zeros */
wire = (universe_wire[pin]-1) << shift;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeUniverse_lock, &lock_context );
for ( i = 0; i<UNIV_NUM_WIRES; i++ ) {
wire_mask[i] &= ~mask;
@@ -1790,27 +1793,27 @@ rtems_interrupt_disable(flags);
mask |= wire;
vmeUniverseWriteReg( mask, mapreg );
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
return 0;
}
VmeUniverseISR
vmeUniverseISRGet(unsigned long vector, void **parg)
{
unsigned long flags;
VmeUniverseISR rval = 0;
volatile UniverseIRQEntry *pe = universeHdlTbl + vector;
rtems_interrupt_lock_context lock_context;
if ( vector>=UNIV_NUM_INT_VECS || ! *pe )
return 0;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeUniverse_lock, &lock_context );
if ( *pe ) {
if (parg)
*parg=(*pe)->usrData;
rval = (*pe)->isr;
}
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
return rval;
}
@@ -2251,8 +2254,8 @@ int
vmeUniverseInstallISR(unsigned long vector, VmeUniverseISR hdl, void *arg)
{
UniverseIRQEntry ip;
unsigned long flags;
volatile UniverseIRQEntry *pe;
rtems_interrupt_lock_context lock_context;
if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !vmeUniverseIrqMgrInstalled)
return -1;
@@ -2265,15 +2268,15 @@ volatile UniverseIRQEntry *pe;
ip->isr=hdl;
ip->usrData=arg;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeUniverse_lock, &lock_context );
if ( *pe ) {
/* oops; someone intervened */
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
free(ip);
return -1;
}
*pe = ip;
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
return 0;
}
@@ -2281,22 +2284,22 @@ int
vmeUniverseRemoveISR(unsigned long vector, VmeUniverseISR hdl, void *arg)
{
UniverseIRQEntry ip;
unsigned long flags;
volatile UniverseIRQEntry *pe;
rtems_interrupt_lock_context lock_context;
if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !vmeUniverseIrqMgrInstalled)
return -1;
pe = universeHdlTbl + vector;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeUniverse_lock, &lock_context );
ip = *pe;
if (!ip || ip->isr!=hdl || ip->usrData!=arg) {
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
return -1;
}
*pe = 0;
rtems_interrupt_enable(flags);
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
free(ip);
return 0;
}
@@ -2304,8 +2307,9 @@ volatile UniverseIRQEntry *pe;
static int
intDoEnDis(unsigned int level, int dis)
{
unsigned long flags, v;
unsigned long v;
int shift;
rtems_interrupt_lock_context lock_context;
if ( ! vmeUniverseIrqMgrInstalled || (shift = lvl2bit(level)) < 0 )
return -1;
@@ -2315,14 +2319,14 @@ int shift;
if ( !dis )
return vmeUniverseReadReg(UNIV_REGOFF_LINT_EN) & v ? 1 : 0;
rtems_interrupt_disable(flags);
rtems_interrupt_lock_acquire( &vmeUniverse_lock, &lock_context );
if ( dis<0 )
vmeUniverseWriteReg( vmeUniverseReadReg(UNIV_REGOFF_LINT_EN) & ~v, UNIV_REGOFF_LINT_EN );
else {
vmeUniverseWriteReg( vmeUniverseReadReg(UNIV_REGOFF_LINT_EN) | v, UNIV_REGOFF_LINT_EN );
}
rtems_interrupt_enable(flags);
return 0;
rtems_interrupt_lock_release( &vmeUniverse_lock, &lock_context );
return 0;
}
int