diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 17 | 
1 files changed, 15 insertions, 2 deletions
| diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 9234be1e66f5..5011ffea4e4b 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -71,6 +71,8 @@  #define RIWAR_WRTYP_ALLOC	0x00006000  #define RIWAR_SIZE_MASK		0x0000003F +static DEFINE_SPINLOCK(fsl_rio_config_lock); +  #define __fsl_read_rio_config(x, addr, err, op)		\  	__asm__ __volatile__(				\  		"1:	"op" %1,0(%2)\n"		\ @@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,  			u8 hopcount, u32 offset, int len, u32 *val)  {  	struct rio_priv *priv = mport->priv; +	unsigned long flags;  	u8 *data;  	u32 rval, err = 0; @@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,  	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))  		return -EINVAL; +	spin_lock_irqsave(&fsl_rio_config_lock, flags); +  	out_be32(&priv->maint_atmu_regs->rowtar,  		 (destid << 22) | (hopcount << 12) | (offset >> 12));  	out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,  		__fsl_read_rio_config(rval, data, err, "lwz");  		break;  	default: +		spin_unlock_irqrestore(&fsl_rio_config_lock, flags);  		return -EINVAL;  	} @@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,  			 err, destid, hopcount, offset);  	} +	spin_unlock_irqrestore(&fsl_rio_config_lock, flags);  	*val = rval;  	return err; @@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,  			u8 hopcount, u32 offset, int len, u32 val)  {  	struct rio_priv *priv = mport->priv; +	unsigned long flags;  	u8 *data; +	int ret = 0; +  	pr_debug  		("fsl_rio_config_write:"  		" index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", @@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,  	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))  		return -EINVAL; +	spin_lock_irqsave(&fsl_rio_config_lock, flags); +  	out_be32(&priv->maint_atmu_regs->rowtar,  		 (destid << 22) | (hopcount << 12) | (offset >> 12));  	out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,  		out_be32((u32 *) data, val);  		break;  	default: -		return -EINVAL; +		ret = -EINVAL;  	} +	spin_unlock_irqrestore(&fsl_rio_config_lock, flags); -	return 0; +	return ret;  }  static void fsl_rio_inbound_mem_init(struct rio_priv *priv) |