aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMurali Karicheri2014-03-31 14:01:13 -0500
committerMurali Karicheri2014-03-31 14:01:13 -0500
commite5dede7526072d91ef13c42be7cb452eb920a05f (patch)
tree3bf93fd11ec1823c15b41b68d036649264fb0d48
parent13a9e63b1c6338715e4247953bfb7e0f2902483f (diff)
parent26f824e1bb27598980b3afa621e62e7e092a8134 (diff)
downloadlinux-v3.8/master-rt.tar.gz
linux-v3.8/master-rt.tar.xz
linux-v3.8/master-rt.zip
Merge remote-tracking branch 'origin/v3.8/rebuild/12-keystone-machine' into master/v3.8/master-rtK2_RT_LINUX_03.08.04_14.03v3.8/master-rt
-rw-r--r--arch/arm/mach-keystone/Makefile2
-rw-r--r--arch/arm/mach-keystone/keystone.c5
-rw-r--r--arch/arm/mach-keystone/keystone.h2
-rw-r--r--arch/arm/mach-keystone/keystone_ecc.c85
4 files changed, 91 insertions, 3 deletions
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
index 543f4464c10..e32836719b3 100644
--- a/arch/arm/mach-keystone/Makefile
+++ b/arch/arm/mach-keystone/Makefile
@@ -1,2 +1,2 @@
1obj-y := keystone.o pm.o 1obj-y := keystone.o pm.o keystone_ecc.o
2obj-$(CONFIG_SMP) += platsmp.o 2obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index bbd1b030109..11f80d7b564 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -203,6 +203,7 @@ static int __init keystone_init_misc(void)
203 void __iomem *rstmux8; 203 void __iomem *rstmux8;
204 int error_irq = 0; 204 int error_irq = 0;
205 u32 val; 205 u32 val;
206 int ret;
206 207
207 /* 208 /*
208 * For WD reset to function, rstmux8 should be configured 209 * For WD reset to function, rstmux8 should be configured
@@ -241,7 +242,9 @@ static int __init keystone_init_misc(void)
241 "a15-l1l2-ecc-err-irq", 0) < 0) { 242 "a15-l1l2-ecc-err-irq", 0) < 0) {
242 WARN_ON("request_irq fail for arm L1/L2 ECC error irq\n"); 243 WARN_ON("request_irq fail for arm L1/L2 ECC error irq\n");
243 } 244 }
244 return 0; 245
246 ret = keystone_init_ddr3_ecc(node);
247 return ret;
245} 248}
246postcore_initcall(keystone_init_misc); 249postcore_initcall(keystone_init_misc);
247 250
diff --git a/arch/arm/mach-keystone/keystone.h b/arch/arm/mach-keystone/keystone.h
index 695df128cf5..3d8f0add4fe 100644
--- a/arch/arm/mach-keystone/keystone.h
+++ b/arch/arm/mach-keystone/keystone.h
@@ -23,5 +23,5 @@ extern void secondary_startup(void);
23extern int __init keystone_pm_runtime_init(void); 23extern int __init keystone_pm_runtime_init(void);
24 24
25extern int __init tci6614_timer_init(void); 25extern int __init tci6614_timer_init(void);
26 26extern int keystone_init_ddr3_ecc(struct device_node *node);
27#endif /* __KEYSTONE_H__ */ 27#endif /* __KEYSTONE_H__ */
diff --git a/arch/arm/mach-keystone/keystone_ecc.c b/arch/arm/mach-keystone/keystone_ecc.c
new file mode 100644
index 00000000000..0243ba06295
--- /dev/null
+++ b/arch/arm/mach-keystone/keystone_ecc.c
@@ -0,0 +1,85 @@
1/*
2 * Copyright 2014 Texas Instruments, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/of_irq.h>
21#include <linux/of_platform.h>
22#include <linux/of_address.h>
23#include <linux/reboot.h>
24#include "keystone.h"
25
26/* DDR3 controller registers */
27#define DDR3_EOI 0x0A0
28#define DDR3_IRQ_STATUS_RAW_SYS 0x0A4
29#define DDR3_IRQ_STATUS_SYS 0x0AC
30#define DDR3_IRQ_ENABLE_SET_SYS 0x0B4
31#define DDR3_IRQ_ENABLE_CLR_SYS 0x0BC
32#define DDR3_ECC_CTRL 0x110
33#define DDR3_ONE_BIT_ECC_ERR_CNT 0x130
34
35#define DDR3_1B_ECC_ERR BIT(5)
36#define DDR3_2B_ECC_ERR BIT(4)
37#define DDR3_WR_ECC_ERR BIT(3)
38
39static irqreturn_t ddr3_ecc_err_irq_handler(int irq, void *reg_virt)
40{
41 int ret = IRQ_NONE;
42 u32 irq_status;
43 void __iomem *ddr_reg = (void __iomem *)reg_virt;
44
45 irq_status = readl(ddr_reg + DDR3_IRQ_STATUS_SYS);
46 if ((irq_status & DDR3_2B_ECC_ERR) ||
47 (irq_status & DDR3_WR_ECC_ERR)) {
48 pr_err("Unrecoverable DDR3 ECC error, irq status 0x%x, "
49 "rebooting kernel ..\n", irq_status);
50 machine_restart(NULL);
51 ret = IRQ_HANDLED;
52 }
53 return ret;
54}
55
56int keystone_init_ddr3_ecc(struct device_node *node)
57{
58 void __iomem *ddr_reg;
59 int error_irq = 0;
60 int ret;
61
62 /* ddr3 controller reg is configured in the sysctrl node at index 0 */
63 ddr_reg = of_iomap(node, 0);
64 if (!ddr_reg) {
65 pr_warn("Warning!! DDR3 controller regs not defined\n");
66 return -ENODEV;
67 }
68
69 /* add DDR3 ECC error handler */
70 error_irq = irq_of_parse_and_map(node, 1);
71 if (!error_irq) {
72 /* No GIC interrupt, need to map CIC2 interupt to GIC */
73 pr_warn("Warning!! DDR3 ECC irq number not defined\n");
74 return -ENODEV;
75 }
76
77 ret = request_irq(error_irq, ddr3_ecc_err_irq_handler, 0,
78 "ddr3-ecc-err-irq", (void *)ddr_reg);
79 if (ret) {
80 WARN_ON("request_irq fail for DDR3 ECC error irq\n");
81 return ret;
82 }
83
84 return 0;
85}