aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-26 19:58:22 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-26 19:58:22 -0400
commit9693ebd4815eefa2b7c8fcc699061a0c8da0c1e7 (patch)
treecd8d8919c18528c26aa78291833b3551c4d33a35 /arch/powerpc/sysdev
parent3fb7933850faf1017c59a675e895ed8f27fef4be (diff)
parent6ff31453161e8614e8ba3b360f8d883a27230e0c (diff)
Merge remote branch 'kumar/merge' into merge
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c9
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c100
2 files changed, 87 insertions, 22 deletions
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 4fcb5a4e60dd..0608b1657da4 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -184,7 +184,8 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
184} 184}
185EXPORT_SYMBOL(fsl_upm_run_pattern); 185EXPORT_SYMBOL(fsl_upm_run_pattern);
186 186
187static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) 187static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl,
188 struct device_node *node)
188{ 189{
189 struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 190 struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
190 191
@@ -198,6 +199,10 @@ static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl)
198 /* Enable interrupts for any detected events */ 199 /* Enable interrupts for any detected events */
199 out_be32(&lbc->lteir, LTEIR_ENABLE); 200 out_be32(&lbc->lteir, LTEIR_ENABLE);
200 201
202 /* Set the monitor timeout value to the maximum for erratum A001 */
203 if (of_device_is_compatible(node, "fsl,elbc"))
204 clrsetbits_be32(&lbc->lbcr, LBCR_BMT, LBCR_BMTPS);
205
201 return 0; 206 return 0;
202} 207}
203 208
@@ -304,7 +309,7 @@ static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
304 309
305 fsl_lbc_ctrl_dev->dev = &dev->dev; 310 fsl_lbc_ctrl_dev->dev = &dev->dev;
306 311
307 ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev); 312 ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev, dev->dev.of_node);
308 if (ret < 0) 313 if (ret < 0)
309 goto err; 314 goto err;
310 315
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 49798532b477..5b206a2fe17c 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -10,7 +10,7 @@
10 * - Added Port-Write message handling 10 * - Added Port-Write message handling
11 * - Added Machine Check exception handling 11 * - Added Machine Check exception handling
12 * 12 *
13 * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. 13 * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc.
14 * Zhang Wei <wei.zhang@freescale.com> 14 * Zhang Wei <wei.zhang@freescale.com>
15 * 15 *
16 * Copyright 2005 MontaVista Software, Inc. 16 * Copyright 2005 MontaVista Software, Inc.
@@ -47,15 +47,33 @@
47#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) 47#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
48#define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) 48#define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq)
49 49
50#define IPWSR_CLEAR 0x98
51#define OMSR_CLEAR 0x1cb3
52#define IMSR_CLEAR 0x491
53#define IDSR_CLEAR 0x91
54#define ODSR_CLEAR 0x1c00
55#define LTLEECSR_ENABLE_ALL 0xFFC000FC
56#define ESCSR_CLEAR 0x07120204
57
58#define RIO_PORT1_EDCSR 0x0640
59#define RIO_PORT2_EDCSR 0x0680
60#define RIO_PORT1_IECSR 0x10130
61#define RIO_PORT2_IECSR 0x101B0
62#define RIO_IM0SR 0x13064
63#define RIO_IM1SR 0x13164
64#define RIO_OM0SR 0x13004
65#define RIO_OM1SR 0x13104
66
50#define RIO_ATMU_REGS_OFFSET 0x10c00 67#define RIO_ATMU_REGS_OFFSET 0x10c00
51#define RIO_P_MSG_REGS_OFFSET 0x11000 68#define RIO_P_MSG_REGS_OFFSET 0x11000
52#define RIO_S_MSG_REGS_OFFSET 0x13000 69#define RIO_S_MSG_REGS_OFFSET 0x13000
53#define RIO_GCCSR 0x13c 70#define RIO_GCCSR 0x13c
54#define RIO_ESCSR 0x158 71#define RIO_ESCSR 0x158
72#define RIO_PORT2_ESCSR 0x178
55#define RIO_CCSR 0x15c 73#define RIO_CCSR 0x15c
56#define RIO_LTLEDCSR 0x0608 74#define RIO_LTLEDCSR 0x0608
57#define RIO_LTLEDCSR_IER 0x80000000 75#define RIO_LTLEDCSR_IER 0x80000000
58#define RIO_LTLEDCSR_PRT 0x01000000 76#define RIO_LTLEDCSR_PRT 0x01000000
59#define RIO_LTLEECSR 0x060c 77#define RIO_LTLEECSR 0x060c
60#define RIO_EPWISR 0x10010 78#define RIO_EPWISR 0x10010
61#define RIO_ISR_AACR 0x10120 79#define RIO_ISR_AACR 0x10120
@@ -88,7 +106,10 @@
88#define RIO_IPWSR_PWD 0x00000008 106#define RIO_IPWSR_PWD 0x00000008
89#define RIO_IPWSR_PWB 0x00000004 107#define RIO_IPWSR_PWB 0x00000004
90 108
91#define RIO_EPWISR_PINT 0x80000000 109/* EPWISR Error match value */
110#define RIO_EPWISR_PINT1 0x80000000
111#define RIO_EPWISR_PINT2 0x40000000
112#define RIO_EPWISR_MU 0x00000002
92#define RIO_EPWISR_PW 0x00000001 113#define RIO_EPWISR_PW 0x00000001
93 114
94#define RIO_MSG_DESC_SIZE 32 115#define RIO_MSG_DESC_SIZE 32
@@ -260,9 +281,7 @@ struct rio_priv {
260static void __iomem *rio_regs_win; 281static void __iomem *rio_regs_win;
261 282
262#ifdef CONFIG_E500 283#ifdef CONFIG_E500
263static int (*saved_mcheck_exception)(struct pt_regs *regs); 284int fsl_rio_mcheck_exception(struct pt_regs *regs)
264
265static int fsl_rio_mcheck_exception(struct pt_regs *regs)
266{ 285{
267 const struct exception_table_entry *entry = NULL; 286 const struct exception_table_entry *entry = NULL;
268 unsigned long reason = mfspr(SPRN_MCSR); 287 unsigned long reason = mfspr(SPRN_MCSR);
@@ -284,11 +303,9 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
284 } 303 }
285 } 304 }
286 305
287 if (saved_mcheck_exception) 306 return 0;
288 return saved_mcheck_exception(regs);
289 else
290 return cur_cpu_spec->machine_check(regs);
291} 307}
308EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception);
292#endif 309#endif
293 310
294/** 311/**
@@ -1064,6 +1081,40 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport)
1064 return rc; 1081 return rc;
1065} 1082}
1066 1083
1084static void port_error_handler(struct rio_mport *port, int offset)
1085{
1086 /*XXX: Error recovery is not implemented, we just clear errors */
1087 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
1088
1089 if (offset == 0) {
1090 out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0);
1091 out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0);
1092 out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
1093 } else {
1094 out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0);
1095 out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0);
1096 out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
1097 }
1098}
1099
1100static void msg_unit_error_handler(struct rio_mport *port)
1101{
1102 struct rio_priv *priv = port->priv;
1103
1104 /*XXX: Error recovery is not implemented, we just clear errors */
1105 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
1106
1107 out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR);
1108 out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR);
1109 out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR);
1110 out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR);
1111
1112 out_be32(&priv->msg_regs->odsr, ODSR_CLEAR);
1113 out_be32(&priv->msg_regs->dsr, IDSR_CLEAR);
1114
1115 out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR);
1116}
1117
1067/** 1118/**
1068 * fsl_rio_port_write_handler - MPC85xx port write interrupt handler 1119 * fsl_rio_port_write_handler - MPC85xx port write interrupt handler
1069 * @irq: Linux interrupt number 1120 * @irq: Linux interrupt number
@@ -1144,10 +1195,22 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1144 } 1195 }
1145 1196
1146pw_done: 1197pw_done:
1147 if (epwisr & RIO_EPWISR_PINT) { 1198 if (epwisr & RIO_EPWISR_PINT1) {
1199 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1200 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1201 port_error_handler(port, 0);
1202 }
1203
1204 if (epwisr & RIO_EPWISR_PINT2) {
1148 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); 1205 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1149 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); 1206 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1150 out_be32(priv->regs_win + RIO_LTLEDCSR, 0); 1207 port_error_handler(port, 1);
1208 }
1209
1210 if (epwisr & RIO_EPWISR_MU) {
1211 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1212 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1213 msg_unit_error_handler(port);
1151 } 1214 }
1152 1215
1153 return IRQ_HANDLED; 1216 return IRQ_HANDLED;
@@ -1258,12 +1321,14 @@ static int fsl_rio_port_write_init(struct rio_mport *mport)
1258 1321
1259 1322
1260 /* Hook up port-write handler */ 1323 /* Hook up port-write handler */
1261 rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0, 1324 rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler,
1262 "port-write", (void *)mport); 1325 IRQF_SHARED, "port-write", (void *)mport);
1263 if (rc < 0) { 1326 if (rc < 0) {
1264 pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); 1327 pr_err("MPC85xx RIO: unable to request inbound doorbell irq");
1265 goto err_out; 1328 goto err_out;
1266 } 1329 }
1330 /* Enable Error Interrupt */
1331 out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL);
1267 1332
1268 INIT_WORK(&priv->pw_work, fsl_pw_dpc); 1333 INIT_WORK(&priv->pw_work, fsl_pw_dpc);
1269 spin_lock_init(&priv->pw_fifo_lock); 1334 spin_lock_init(&priv->pw_fifo_lock);
@@ -1538,11 +1603,6 @@ int fsl_rio_setup(struct platform_device *dev)
1538 fsl_rio_doorbell_init(port); 1603 fsl_rio_doorbell_init(port);
1539 fsl_rio_port_write_init(port); 1604 fsl_rio_port_write_init(port);
1540 1605
1541#ifdef CONFIG_E500
1542 saved_mcheck_exception = ppc_md.machine_check_exception;
1543 ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
1544#endif
1545
1546 return 0; 1606 return 0;
1547err: 1607err:
1548 iounmap(priv->regs_win); 1608 iounmap(priv->regs_win);