From 2b9558b9ded281ca8db7f4f82b8f9de63ee43e42 Mon Sep 17 00:00:00 2001 From: Thomas Moll Date: Wed, 26 May 2010 14:44:05 -0700 Subject: [PATCH] --- yaml --- r: 198813 b: refs/heads/master c: bd4fb654e3a0d83ca8cb138c5e3e6e65407e119c h: refs/heads/master i: 198811: 26240ffb733154773af3232676a31df685eb6d01 v: v3 --- [refs] | 2 +- trunk/arch/powerpc/sysdev/fsl_rio.c | 37 +++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 0c65871684d6..65969e21d05e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 679395fdaa68de39aaf2ddf7298b504fed9622d3 +refs/heads/master: bd4fb654e3a0d83ca8cb138c5e3e6e65407e119c diff --git a/trunk/arch/powerpc/sysdev/fsl_rio.c b/trunk/arch/powerpc/sysdev/fsl_rio.c index 4646cc7aa93a..cd37e49e7034 100644 --- a/trunk/arch/powerpc/sysdev/fsl_rio.c +++ b/trunk/arch/powerpc/sysdev/fsl_rio.c @@ -1,6 +1,10 @@ /* * Freescale MPC85xx/MPC86xx RapidIO support * + * Copyright 2009 Sysgo AG + * Thomas Moll + * - fixed maintenance access routines, check for aligned access + * * Copyright 2009 Integrated Device Technology, Inc. * Alex Bounine * - Added Port-Write message handling @@ -371,10 +375,17 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, pr_debug ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", index, destid, hopcount, offset, len); + + /* 16MB maintenance window possible */ + /* allow only aligned access to maintenance registers */ + if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) + return -EINVAL; + out_be32(&priv->maint_atmu_regs->rowtar, - (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); + (destid << 22) | (hopcount << 12) | (offset >> 12)); + out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); - data = (u8 *) priv->maint_win + offset; + data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1)); switch (len) { case 1: __fsl_read_rio_config(rval, data, err, "lbz"); @@ -382,9 +393,11 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, case 2: __fsl_read_rio_config(rval, data, err, "lhz"); break; - default: + case 4: __fsl_read_rio_config(rval, data, err, "lwz"); break; + default: + return -EINVAL; } if (err) { @@ -419,10 +432,17 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, pr_debug ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", index, destid, hopcount, offset, len, val); + + /* 16MB maintenance windows possible */ + /* allow only aligned access to maintenance registers */ + if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) + return -EINVAL; + out_be32(&priv->maint_atmu_regs->rowtar, - (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); + (destid << 22) | (hopcount << 12) | (offset >> 12)); + out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); - data = (u8 *) priv->maint_win + offset; + data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1)); switch (len) { case 1: out_8((u8 *) data, val); @@ -430,9 +450,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, case 2: out_be16((u16 *) data, val); break; - default: + case 4: out_be32((u32 *) data, val); break; + default: + return -EINVAL; } return 0; @@ -1483,7 +1505,8 @@ int fsl_rio_setup(struct of_device *dev) /* Configure maintenance transaction window */ out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12); - out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */ + out_be32(&priv->maint_atmu_regs->rowar, + 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1)); priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);