diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 412763672d23..9725369d432a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #define RIO_ATMU_REGS_OFFSET 0x10c00 | 50 | #define RIO_ATMU_REGS_OFFSET 0x10c00 |
51 | #define RIO_P_MSG_REGS_OFFSET 0x11000 | 51 | #define RIO_P_MSG_REGS_OFFSET 0x11000 |
52 | #define RIO_S_MSG_REGS_OFFSET 0x13000 | 52 | #define RIO_S_MSG_REGS_OFFSET 0x13000 |
53 | #define RIO_GCCSR 0x13c | ||
53 | #define RIO_ESCSR 0x158 | 54 | #define RIO_ESCSR 0x158 |
54 | #define RIO_CCSR 0x15c | 55 | #define RIO_CCSR 0x15c |
55 | #define RIO_LTLEDCSR 0x0608 | 56 | #define RIO_LTLEDCSR 0x0608 |
@@ -87,6 +88,9 @@ | |||
87 | #define RIO_IPWSR_PWD 0x00000008 | 88 | #define RIO_IPWSR_PWD 0x00000008 |
88 | #define RIO_IPWSR_PWB 0x00000004 | 89 | #define RIO_IPWSR_PWB 0x00000004 |
89 | 90 | ||
91 | #define RIO_EPWISR_PINT 0x80000000 | ||
92 | #define RIO_EPWISR_PW 0x00000001 | ||
93 | |||
90 | #define RIO_MSG_DESC_SIZE 32 | 94 | #define RIO_MSG_DESC_SIZE 32 |
91 | #define RIO_MSG_BUFFER_SIZE 4096 | 95 | #define RIO_MSG_BUFFER_SIZE 4096 |
92 | #define RIO_MIN_TX_RING_SIZE 2 | 96 | #define RIO_MIN_TX_RING_SIZE 2 |
@@ -1082,18 +1086,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1082 | struct rio_priv *priv = port->priv; | 1086 | struct rio_priv *priv = port->priv; |
1083 | u32 epwisr, tmp; | 1087 | u32 epwisr, tmp; |
1084 | 1088 | ||
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); | 1089 | epwisr = in_be32(priv->regs_win + RIO_EPWISR); |
1089 | if (epwisr & 0x80000000) { | 1090 | if (!(epwisr & RIO_EPWISR_PW)) |
1090 | tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); | 1091 | goto pw_done; |
1091 | pr_info("RIO_LTLEDCSR = 0x%x\n", tmp); | ||
1092 | out_be32(priv->regs_win + RIO_LTLEDCSR, 0); | ||
1093 | } | ||
1094 | 1092 | ||
1095 | if (!(epwisr & 0x00000001)) | 1093 | ipwmr = in_be32(&priv->msg_regs->pwmr); |
1096 | return IRQ_HANDLED; | 1094 | ipwsr = in_be32(&priv->msg_regs->pwsr); |
1097 | 1095 | ||
1098 | #ifdef DEBUG_PW | 1096 | #ifdef DEBUG_PW |
1099 | pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); | 1097 | pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); |
@@ -1109,20 +1107,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1109 | pr_debug(" PWB"); | 1107 | pr_debug(" PWB"); |
1110 | pr_debug(" )\n"); | 1108 | pr_debug(" )\n"); |
1111 | #endif | 1109 | #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 */ | 1110 | /* Schedule deferred processing if PW was received */ |
1127 | if (ipwsr & RIO_IPWSR_QFI) { | 1111 | if (ipwsr & RIO_IPWSR_QFI) { |
1128 | /* Save PW message (if there is room in FIFO), | 1112 | /* Save PW message (if there is room in FIFO), |
@@ -1134,16 +1118,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1134 | RIO_PW_MSG_SIZE); | 1118 | RIO_PW_MSG_SIZE); |
1135 | } else { | 1119 | } else { |
1136 | priv->port_write_msg.discard_count++; | 1120 | priv->port_write_msg.discard_count++; |
1137 | pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", | 1121 | pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", |
1138 | priv->port_write_msg.discard_count); | 1122 | priv->port_write_msg.discard_count); |
1139 | } | 1123 | } |
1124 | /* Clear interrupt and issue Clear Queue command. This allows | ||
1125 | * another port-write to be received. | ||
1126 | */ | ||
1127 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI); | ||
1128 | out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); | ||
1129 | |||
1140 | schedule_work(&priv->pw_work); | 1130 | schedule_work(&priv->pw_work); |
1141 | } | 1131 | } |
1142 | 1132 | ||
1143 | /* Issue Clear Queue command. This allows another | 1133 | if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) { |
1144 | * port-write to be received. | 1134 | priv->port_write_msg.err_count++; |
1145 | */ | 1135 | pr_debug("RIO: Port-Write Transaction Err (%d)\n", |
1146 | out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); | 1136 | priv->port_write_msg.err_count); |
1137 | /* Clear Transaction Error: port-write controller should be | ||
1138 | * disabled when clearing this error | ||
1139 | */ | ||
1140 | out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE); | ||
1141 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE); | ||
1142 | out_be32(&priv->msg_regs->pwmr, ipwmr); | ||
1143 | } | ||
1144 | |||
1145 | if (ipwsr & RIO_IPWSR_PWD) { | ||
1146 | priv->port_write_msg.discard_count++; | ||
1147 | pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n", | ||
1148 | priv->port_write_msg.discard_count); | ||
1149 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD); | ||
1150 | } | ||
1151 | |||
1152 | pw_done: | ||
1153 | if (epwisr & RIO_EPWISR_PINT) { | ||
1154 | tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); | ||
1155 | pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); | ||
1156 | out_be32(priv->regs_win + RIO_LTLEDCSR, 0); | ||
1157 | } | ||
1147 | 1158 | ||
1148 | return IRQ_HANDLED; | 1159 | return IRQ_HANDLED; |
1149 | } | 1160 | } |
@@ -1461,6 +1472,7 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1461 | port->host_deviceid = fsl_rio_get_hdid(port->id); | 1472 | port->host_deviceid = fsl_rio_get_hdid(port->id); |
1462 | 1473 | ||
1463 | port->priv = priv; | 1474 | port->priv = priv; |
1475 | port->phys_efptr = 0x100; | ||
1464 | rio_register_mport(port); | 1476 | rio_register_mport(port); |
1465 | 1477 | ||
1466 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); | 1478 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); |
@@ -1508,6 +1520,12 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1508 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", | 1520 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", |
1509 | port->sys_size ? 65536 : 256); | 1521 | port->sys_size ? 65536 : 256); |
1510 | 1522 | ||
1523 | if (port->host_deviceid >= 0) | ||
1524 | out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | | ||
1525 | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); | ||
1526 | else | ||
1527 | out_be32(priv->regs_win + RIO_GCCSR, 0x00000000); | ||
1528 | |||
1511 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win | 1529 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win |
1512 | + RIO_ATMU_REGS_OFFSET); | 1530 | + RIO_ATMU_REGS_OFFSET); |
1513 | priv->maint_atmu_regs = priv->atmu_regs + 1; | 1531 | priv->maint_atmu_regs = priv->atmu_regs + 1; |