aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorThomas Moll <thomas.moll@sysgo.com>2010-05-26 17:44:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:51 -0400
commitbd4fb654e3a0d83ca8cb138c5e3e6e65407e119c (patch)
tree6fd7292e5a30f4d8c1545b5f73c7d8b5e26e94cb /arch/powerpc/sysdev
parent679395fdaa68de39aaf2ddf7298b504fed9622d3 (diff)
rapidio: fix maintenance access to higher memory areas
Fix the maintenance access functions to farend RapidIO devices. 1. Fixed shift of the given offset, to open the maintenance window 2. Mask offset to limit access to the opened maintenance window 3. Added extended destid part to rowtear register, required for 16bit mode This method is matching maintenance transactions generation described by Freescale in the appnote AN2932. With this modification full access to a 16MB maintenance window is possible, this patch is required for IDT cps switches. For easier handling of the access routines, the access was limited to aligned memory regions. This should be no problem because all registers are 32bit wide. Signed-off-by: Thomas Moll <thomas.moll@sysgo.com> Tested-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 4646cc7aa93a..cd37e49e7034 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,6 +1,10 @@
1/* 1/*
2 * Freescale MPC85xx/MPC86xx RapidIO support 2 * Freescale MPC85xx/MPC86xx RapidIO support
3 * 3 *
4 * Copyright 2009 Sysgo AG
5 * Thomas Moll <thomas.moll@sysgo.com>
6 * - fixed maintenance access routines, check for aligned access
7 *
4 * Copyright 2009 Integrated Device Technology, Inc. 8 * Copyright 2009 Integrated Device Technology, Inc.
5 * Alex Bounine <alexandre.bounine@idt.com> 9 * Alex Bounine <alexandre.bounine@idt.com>
6 * - Added Port-Write message handling 10 * - Added Port-Write message handling
@@ -371,10 +375,17 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
371 pr_debug 375 pr_debug
372 ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", 376 ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
373 index, destid, hopcount, offset, len); 377 index, destid, hopcount, offset, len);
378
379 /* 16MB maintenance window possible */
380 /* allow only aligned access to maintenance registers */
381 if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
382 return -EINVAL;
383
374 out_be32(&priv->maint_atmu_regs->rowtar, 384 out_be32(&priv->maint_atmu_regs->rowtar,
375 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); 385 (destid << 22) | (hopcount << 12) | (offset >> 12));
386 out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
376 387
377 data = (u8 *) priv->maint_win + offset; 388 data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1));
378 switch (len) { 389 switch (len) {
379 case 1: 390 case 1:
380 __fsl_read_rio_config(rval, data, err, "lbz"); 391 __fsl_read_rio_config(rval, data, err, "lbz");
@@ -382,9 +393,11 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
382 case 2: 393 case 2:
383 __fsl_read_rio_config(rval, data, err, "lhz"); 394 __fsl_read_rio_config(rval, data, err, "lhz");
384 break; 395 break;
385 default: 396 case 4:
386 __fsl_read_rio_config(rval, data, err, "lwz"); 397 __fsl_read_rio_config(rval, data, err, "lwz");
387 break; 398 break;
399 default:
400 return -EINVAL;
388 } 401 }
389 402
390 if (err) { 403 if (err) {
@@ -419,10 +432,17 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
419 pr_debug 432 pr_debug
420 ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", 433 ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
421 index, destid, hopcount, offset, len, val); 434 index, destid, hopcount, offset, len, val);
435
436 /* 16MB maintenance windows possible */
437 /* allow only aligned access to maintenance registers */
438 if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
439 return -EINVAL;
440
422 out_be32(&priv->maint_atmu_regs->rowtar, 441 out_be32(&priv->maint_atmu_regs->rowtar,
423 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); 442 (destid << 22) | (hopcount << 12) | (offset >> 12));
443 out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
424 444
425 data = (u8 *) priv->maint_win + offset; 445 data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1));
426 switch (len) { 446 switch (len) {
427 case 1: 447 case 1:
428 out_8((u8 *) data, val); 448 out_8((u8 *) data, val);
@@ -430,9 +450,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
430 case 2: 450 case 2:
431 out_be16((u16 *) data, val); 451 out_be16((u16 *) data, val);
432 break; 452 break;
433 default: 453 case 4:
434 out_be32((u32 *) data, val); 454 out_be32((u32 *) data, val);
435 break; 455 break;
456 default:
457 return -EINVAL;
436 } 458 }
437 459
438 return 0; 460 return 0;
@@ -1483,7 +1505,8 @@ int fsl_rio_setup(struct of_device *dev)
1483 1505
1484 /* Configure maintenance transaction window */ 1506 /* Configure maintenance transaction window */
1485 out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12); 1507 out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12);
1486 out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */ 1508 out_be32(&priv->maint_atmu_regs->rowar,
1509 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1));
1487 1510
1488 priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE); 1511 priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
1489 1512