aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>2013-06-11 06:11:19 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-17 19:46:06 -0400
commit36dd68319c7b56a76ed450b0e470067b5d74b9b2 (patch)
treea52728d996ead41a45953a3c6b585b8cdc32a85b /drivers/memory
parentd777f98bfa44e5a2748603276e9e9fb6ab999079 (diff)
memory: tegra30-mc: Fix IRQ handler.
In Tegra30 any memory controller interrupt would cause an infinite loop in the IRQ handler. Additionally, a garbage pointer was used to read the MC status registers, which causes wrong values to be printed if a MC error occurred. Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/tegra30-mc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c
index f4ae074badc3..58d2979b4035 100644
--- a/drivers/memory/tegra30-mc.c
+++ b/drivers/memory/tegra30-mc.c
@@ -218,7 +218,7 @@ static void tegra30_mc_decode(struct tegra30_mc *mc, int n)
218 return; 218 return;
219 } 219 }
220 220
221 err = readl(mc + MC_ERR_STATUS); 221 err = mc_readl(mc, MC_ERR_STATUS);
222 222
223 type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT; 223 type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT;
224 perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >> 224 perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >>
@@ -235,7 +235,7 @@ static void tegra30_mc_decode(struct tegra30_mc *mc, int n)
235 if (cid < ARRAY_SIZE(tegra30_mc_client)) 235 if (cid < ARRAY_SIZE(tegra30_mc_client))
236 client = tegra30_mc_client[cid]; 236 client = tegra30_mc_client[cid];
237 237
238 addr = readl(mc + MC_ERR_ADR); 238 addr = mc_readl(mc, MC_ERR_ADR);
239 239
240 dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n", 240 dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n",
241 mc_int_err[idx], err, addr, client, 241 mc_int_err[idx], err, addr, client,
@@ -313,8 +313,11 @@ static irqreturn_t tegra30_mc_isr(int irq, void *data)
313 mask &= stat; 313 mask &= stat;
314 if (!mask) 314 if (!mask)
315 return IRQ_NONE; 315 return IRQ_NONE;
316 while ((bit = ffs(mask)) != 0) 316 while ((bit = ffs(mask)) != 0) {
317 tegra30_mc_decode(mc, bit - 1); 317 tegra30_mc_decode(mc, bit - 1);
318 mask &= ~BIT(bit - 1);
319 }
320
318 mc_writel(mc, stat, MC_INTSTATUS); 321 mc_writel(mc, stat, MC_INTSTATUS);
319 return IRQ_HANDLED; 322 return IRQ_HANDLED;
320} 323}