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 @@ | |||
71 | #define RIWAR_WRTYP_ALLOC 0x00006000 | 71 | #define RIWAR_WRTYP_ALLOC 0x00006000 |
72 | #define RIWAR_SIZE_MASK 0x0000003F | 72 | #define RIWAR_SIZE_MASK 0x0000003F |
73 | 73 | ||
74 | static DEFINE_SPINLOCK(fsl_rio_config_lock); | ||
75 | |||
74 | #define __fsl_read_rio_config(x, addr, err, op) \ | 76 | #define __fsl_read_rio_config(x, addr, err, op) \ |
75 | __asm__ __volatile__( \ | 77 | __asm__ __volatile__( \ |
76 | "1: "op" %1,0(%2)\n" \ | 78 | "1: "op" %1,0(%2)\n" \ |
@@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, | |||
184 | u8 hopcount, u32 offset, int len, u32 *val) | 186 | u8 hopcount, u32 offset, int len, u32 *val) |
185 | { | 187 | { |
186 | struct rio_priv *priv = mport->priv; | 188 | struct rio_priv *priv = mport->priv; |
189 | unsigned long flags; | ||
187 | u8 *data; | 190 | u8 *data; |
188 | u32 rval, err = 0; | 191 | u32 rval, err = 0; |
189 | 192 | ||
@@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, | |||
197 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) | 200 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) |
198 | return -EINVAL; | 201 | return -EINVAL; |
199 | 202 | ||
203 | spin_lock_irqsave(&fsl_rio_config_lock, flags); | ||
204 | |||
200 | out_be32(&priv->maint_atmu_regs->rowtar, | 205 | out_be32(&priv->maint_atmu_regs->rowtar, |
201 | (destid << 22) | (hopcount << 12) | (offset >> 12)); | 206 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
202 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); | 207 | 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, | |||
213 | __fsl_read_rio_config(rval, data, err, "lwz"); | 218 | __fsl_read_rio_config(rval, data, err, "lwz"); |
214 | break; | 219 | break; |
215 | default: | 220 | default: |
221 | spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | ||
216 | return -EINVAL; | 222 | return -EINVAL; |
217 | } | 223 | } |
218 | 224 | ||
@@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, | |||
221 | err, destid, hopcount, offset); | 227 | err, destid, hopcount, offset); |
222 | } | 228 | } |
223 | 229 | ||
230 | spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | ||
224 | *val = rval; | 231 | *val = rval; |
225 | 232 | ||
226 | return err; | 233 | return err; |
@@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, | |||
244 | u8 hopcount, u32 offset, int len, u32 val) | 251 | u8 hopcount, u32 offset, int len, u32 val) |
245 | { | 252 | { |
246 | struct rio_priv *priv = mport->priv; | 253 | struct rio_priv *priv = mport->priv; |
254 | unsigned long flags; | ||
247 | u8 *data; | 255 | u8 *data; |
256 | int ret = 0; | ||
257 | |||
248 | pr_debug | 258 | pr_debug |
249 | ("fsl_rio_config_write:" | 259 | ("fsl_rio_config_write:" |
250 | " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", | 260 | " 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, | |||
255 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) | 265 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) |
256 | return -EINVAL; | 266 | return -EINVAL; |
257 | 267 | ||
268 | spin_lock_irqsave(&fsl_rio_config_lock, flags); | ||
269 | |||
258 | out_be32(&priv->maint_atmu_regs->rowtar, | 270 | out_be32(&priv->maint_atmu_regs->rowtar, |
259 | (destid << 22) | (hopcount << 12) | (offset >> 12)); | 271 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
260 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); | 272 | 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, | |||
271 | out_be32((u32 *) data, val); | 283 | out_be32((u32 *) data, val); |
272 | break; | 284 | break; |
273 | default: | 285 | default: |
274 | return -EINVAL; | 286 | ret = -EINVAL; |
275 | } | 287 | } |
288 | spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | ||
276 | 289 | ||
277 | return 0; | 290 | return ret; |
278 | } | 291 | } |
279 | 292 | ||
280 | static void fsl_rio_inbound_mem_init(struct rio_priv *priv) | 293 | static void fsl_rio_inbound_mem_init(struct rio_priv *priv) |