diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2010-10-27 18:34:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:03:15 -0400 |
commit | 93e2cbd24e71f5eedf6e49e075973fda9b2135e8 (patch) | |
tree | 123262c548a447dc313557db8d951c7501b821e5 /arch | |
parent | 2c70f022e2e1b1493e157dbc3796b1f70a3ff162 (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')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 68 |
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 | |||
1151 | pw_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 | } |