aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2010-10-27 18:34:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:15 -0400
commit93e2cbd24e71f5eedf6e49e075973fda9b2135e8 (patch)
tree123262c548a447dc313557db8d951c7501b821e5 /arch/powerpc
parent2c70f022e2e1b1493e157dbc3796b1f70a3ff162 (diff)
rapidio:powerpc/85xx: modify RIO port-write interrupt handler
- Rearrange RIO port-write interrupt handling to perform message buffering as soon as possible. - Modify to disable port-write controller when clearing Transaction Error (TE) bit. Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: Thomas Moll <thomas.moll@sysgo.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Kumar Gala <galak@kernel.crashing.org> Cc: Micha Nelissen <micha@neli.hopto.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 412763672d23..ed2ec7154917 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -87,6 +87,9 @@
87#define RIO_IPWSR_PWD 0x00000008 87#define RIO_IPWSR_PWD 0x00000008
88#define RIO_IPWSR_PWB 0x00000004 88#define RIO_IPWSR_PWB 0x00000004
89 89
90#define RIO_EPWISR_PINT 0x80000000
91#define RIO_EPWISR_PW 0x00000001
92
90#define RIO_MSG_DESC_SIZE 32 93#define RIO_MSG_DESC_SIZE 32
91#define RIO_MSG_BUFFER_SIZE 4096 94#define RIO_MSG_BUFFER_SIZE 4096
92#define RIO_MIN_TX_RING_SIZE 2 95#define RIO_MIN_TX_RING_SIZE 2
@@ -1082,18 +1085,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1082 struct rio_priv *priv = port->priv; 1085 struct rio_priv *priv = port->priv;
1083 u32 epwisr, tmp; 1086 u32 epwisr, tmp;
1084 1087
1085 ipwmr = in_be32(&priv->msg_regs->pwmr);
1086 ipwsr = in_be32(&priv->msg_regs->pwsr);
1087
1088 epwisr = in_be32(priv->regs_win + RIO_EPWISR); 1088 epwisr = in_be32(priv->regs_win + RIO_EPWISR);
1089 if (epwisr & 0x80000000) { 1089 if (!(epwisr & RIO_EPWISR_PW))
1090 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); 1090 goto pw_done;
1091 pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
1092 out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
1093 }
1094 1091
1095 if (!(epwisr & 0x00000001)) 1092 ipwmr = in_be32(&priv->msg_regs->pwmr);
1096 return IRQ_HANDLED; 1093 ipwsr = in_be32(&priv->msg_regs->pwsr);
1097 1094
1098#ifdef DEBUG_PW 1095#ifdef DEBUG_PW
1099 pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); 1096 pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
@@ -1109,20 +1106,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1109 pr_debug(" PWB"); 1106 pr_debug(" PWB");
1110 pr_debug(" )\n"); 1107 pr_debug(" )\n");
1111#endif 1108#endif
1112 out_be32(&priv->msg_regs->pwsr,
1113 ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
1114
1115 if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
1116 priv->port_write_msg.err_count++;
1117 pr_info("RIO: Port-Write Transaction Err (%d)\n",
1118 priv->port_write_msg.err_count);
1119 }
1120 if (ipwsr & RIO_IPWSR_PWD) {
1121 priv->port_write_msg.discard_count++;
1122 pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
1123 priv->port_write_msg.discard_count);
1124 }
1125
1126 /* Schedule deferred processing if PW was received */ 1109 /* Schedule deferred processing if PW was received */
1127 if (ipwsr & RIO_IPWSR_QFI) { 1110 if (ipwsr & RIO_IPWSR_QFI) {
1128 /* Save PW message (if there is room in FIFO), 1111 /* Save PW message (if there is room in FIFO),
@@ -1134,16 +1117,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1134 RIO_PW_MSG_SIZE); 1117 RIO_PW_MSG_SIZE);
1135 } else { 1118 } else {
1136 priv->port_write_msg.discard_count++; 1119 priv->port_write_msg.discard_count++;
1137 pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", 1120 pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
1138 priv->port_write_msg.discard_count); 1121 priv->port_write_msg.discard_count);
1139 } 1122 }
1123 /* Clear interrupt and issue Clear Queue command. This allows
1124 * another port-write to be received.
1125 */
1126 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI);
1127 out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
1128
1140 schedule_work(&priv->pw_work); 1129 schedule_work(&priv->pw_work);
1141 } 1130 }
1142 1131
1143 /* Issue Clear Queue command. This allows another 1132 if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
1144 * port-write to be received. 1133 priv->port_write_msg.err_count++;
1145 */ 1134 pr_debug("RIO: Port-Write Transaction Err (%d)\n",
1146 out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); 1135 priv->port_write_msg.err_count);
1136 /* Clear Transaction Error: port-write controller should be
1137 * disabled when clearing this error
1138 */
1139 out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
1140 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE);
1141 out_be32(&priv->msg_regs->pwmr, ipwmr);
1142 }
1143
1144 if (ipwsr & RIO_IPWSR_PWD) {
1145 priv->port_write_msg.discard_count++;
1146 pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
1147 priv->port_write_msg.discard_count);
1148 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD);
1149 }
1150
1151pw_done:
1152 if (epwisr & RIO_EPWISR_PINT) {
1153 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1154 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1155 out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
1156 }
1147 1157
1148 return IRQ_HANDLED; 1158 return IRQ_HANDLED;
1149} 1159}