[PATCH] Add adm8211 802.11b wireless driver
[pandora-kernel.git] / drivers / net / ioc3-eth.c
index 3ca1e8e..0834ef0 100644 (file)
@@ -48,6 +48,7 @@
 #ifdef CONFIG_SERIAL_8250
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
 #endif
 
 #include <linux/netdevice.h>
@@ -1151,13 +1152,41 @@ static int ioc3_is_menet(struct pci_dev *pdev)
  * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
  * around ioc3 oddities in this respect.
  *
- * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
+ * The IOC3 serials use a 22MHz clock rate with an additional divider which
+ * can be programmed in the SCR register if the DLAB bit is set.
+ *
+ * Register to interrupt zero because we share the interrupt with
+ * the serial driver which we don't properly support yet.
+ *
+ * Can't use UPF_IOREMAP as the whole of IOC3 resources have already been
+ * registered.
  */
+static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
+{
+#define COSMISC_CONSTANT 6
+
+       struct uart_port port = {
+               .irq            = 0,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = (22000000 << 1) / COSMISC_CONSTANT,
+
+               .membase        = (unsigned char __iomem *) uart,
+               .mapbase        = (unsigned long) uart,
+       };
+       unsigned char lcr;
+
+       lcr = uart->iu_lcr;
+       uart->iu_lcr = lcr | UART_LCR_DLAB;
+       uart->iu_scr = COSMISC_CONSTANT,
+       uart->iu_lcr = lcr;
+       uart->iu_lcr;
+       serial8250_register_port(&port);
+}
 
 static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
 {
-       struct uart_port port;
-
        /*
         * We need to recognice and treat the fourth MENET serial as it
         * 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)
                return;
 
        /*
-        * Register to interrupt zero because we share the interrupt with
-        * the serial driver which we don't properly support yet.
-        *
-        * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
-        * been registered.
+        * Switch IOC3 to PIO mode.  It probably already was but let's be
+        * paranoid
         */
-       memset(&port, 0, sizeof(port));
-       port.irq      = 0;
-       port.flags    = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
-       port.iotype   = UPIO_MEM;
-       port.regshift = 0;
-       port.uartclk  = 22000000 / 3;
-
-       port.membase  = (unsigned char *) &ioc3->sregs.uarta;
-       serial8250_register_port(&port);
-
-       port.membase  = (unsigned char *) &ioc3->sregs.uartb;
-       serial8250_register_port(&port);
+       ioc3->gpcr_s = GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL;
+       ioc3->gpcr_s;
+       ioc3->gppr_6 = 0;
+       ioc3->gppr_6;
+       ioc3->gppr_7 = 0;
+       ioc3->gppr_7;
+       ioc3->sscr_a = ioc3->sscr_a & ~SSCR_DMA_EN;
+       ioc3->sscr_a;
+       ioc3->sscr_b = ioc3->sscr_b & ~SSCR_DMA_EN;
+       ioc3->sscr_b;
+       /* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */
+       ioc3->sio_iec &= ~ (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL |
+                           SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER |
+                           SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS |
+                           SIO_IR_SA_TX_EXPLICIT | SIO_IR_SA_MEMERR);
+       ioc3->sio_iec |= SIO_IR_SA_INT;
+       ioc3->sscr_a = 0;
+       ioc3->sio_iec &= ~ (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL |
+                           SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER |
+                           SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS |
+                           SIO_IR_SB_TX_EXPLICIT | SIO_IR_SB_MEMERR);
+       ioc3->sio_iec |= SIO_IR_SB_INT;
+       ioc3->sscr_b = 0;
+
+       ioc3_8250_register(&ioc3->sregs.uarta);
+       ioc3_8250_register(&ioc3->sregs.uartb);
 }
 #endif