aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ioc3-eth.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 3ca1e8ece548..0834ef0eddb4 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -48,6 +48,7 @@
48#ifdef CONFIG_SERIAL_8250 48#ifdef CONFIG_SERIAL_8250
49#include <linux/serial_core.h> 49#include <linux/serial_core.h>
50#include <linux/serial_8250.h> 50#include <linux/serial_8250.h>
51#include <linux/serial_reg.h>
51#endif 52#endif
52 53
53#include <linux/netdevice.h> 54#include <linux/netdevice.h>
@@ -1151,13 +1152,41 @@ static int ioc3_is_menet(struct pci_dev *pdev)
1151 * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working 1152 * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
1152 * around ioc3 oddities in this respect. 1153 * around ioc3 oddities in this respect.
1153 * 1154 *
1154 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. 1155 * The IOC3 serials use a 22MHz clock rate with an additional divider which
1156 * can be programmed in the SCR register if the DLAB bit is set.
1157 *
1158 * Register to interrupt zero because we share the interrupt with
1159 * the serial driver which we don't properly support yet.
1160 *
1161 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already been
1162 * registered.
1155 */ 1163 */
1164static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
1165{
1166#define COSMISC_CONSTANT 6
1167
1168 struct uart_port port = {
1169 .irq = 0,
1170 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
1171 .iotype = UPIO_MEM,
1172 .regshift = 0,
1173 .uartclk = (22000000 << 1) / COSMISC_CONSTANT,
1174
1175 .membase = (unsigned char __iomem *) uart,
1176 .mapbase = (unsigned long) uart,
1177 };
1178 unsigned char lcr;
1179
1180 lcr = uart->iu_lcr;
1181 uart->iu_lcr = lcr | UART_LCR_DLAB;
1182 uart->iu_scr = COSMISC_CONSTANT,
1183 uart->iu_lcr = lcr;
1184 uart->iu_lcr;
1185 serial8250_register_port(&port);
1186}
1156 1187
1157static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) 1188static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1158{ 1189{
1159 struct uart_port port;
1160
1161 /* 1190 /*
1162 * We need to recognice and treat the fourth MENET serial as it 1191 * We need to recognice and treat the fourth MENET serial as it
1163 * does not have an SuperIO chip attached to it, therefore attempting 1192 * does not have an SuperIO chip attached to it, therefore attempting
@@ -1171,24 +1200,35 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1171 return; 1200 return;
1172 1201
1173 /* 1202 /*
1174 * Register to interrupt zero because we share the interrupt with 1203 * Switch IOC3 to PIO mode. It probably already was but let's be
1175 * the serial driver which we don't properly support yet. 1204 * paranoid
1176 *
1177 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
1178 * been registered.
1179 */ 1205 */
1180 memset(&port, 0, sizeof(port)); 1206 ioc3->gpcr_s = GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL;
1181 port.irq = 0; 1207 ioc3->gpcr_s;
1182 port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; 1208 ioc3->gppr_6 = 0;
1183 port.iotype = UPIO_MEM; 1209 ioc3->gppr_6;
1184 port.regshift = 0; 1210 ioc3->gppr_7 = 0;
1185 port.uartclk = 22000000 / 3; 1211 ioc3->gppr_7;
1186 1212 ioc3->sscr_a = ioc3->sscr_a & ~SSCR_DMA_EN;
1187 port.membase = (unsigned char *) &ioc3->sregs.uarta; 1213 ioc3->sscr_a;
1188 serial8250_register_port(&port); 1214 ioc3->sscr_b = ioc3->sscr_b & ~SSCR_DMA_EN;
1189 1215 ioc3->sscr_b;
1190 port.membase = (unsigned char *) &ioc3->sregs.uartb; 1216 /* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */
1191 serial8250_register_port(&port); 1217 ioc3->sio_iec &= ~ (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL |
1218 SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER |
1219 SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS |
1220 SIO_IR_SA_TX_EXPLICIT | SIO_IR_SA_MEMERR);
1221 ioc3->sio_iec |= SIO_IR_SA_INT;
1222 ioc3->sscr_a = 0;
1223 ioc3->sio_iec &= ~ (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL |
1224 SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER |
1225 SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS |
1226 SIO_IR_SB_TX_EXPLICIT | SIO_IR_SB_MEMERR);
1227 ioc3->sio_iec |= SIO_IR_SB_INT;
1228 ioc3->sscr_b = 0;
1229
1230 ioc3_8250_register(&ioc3->sregs.uarta);
1231 ioc3_8250_register(&ioc3->sregs.uartb);
1192} 1232}
1193#endif 1233#endif
1194 1234