fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / serial / imx.c
index 4d53fb5..e216dcf 100644 (file)
@@ -25,7 +25,6 @@
  * [29-Mar-2005] Mike Lee
  * Added hardware handshake
  */
-#include <linux/config.h>
 
 #if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -45,6 +44,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
+#include <asm/arch/imx-uart.h>
 
 /* We've been assigned a range on the "Low-density serial ports" major */
 #define SERIAL_IMX_MAJOR       204
@@ -73,7 +73,8 @@ struct imx_port {
        struct uart_port        port;
        struct timer_list       timer;
        unsigned int            old_status;
-       int txirq,rxirq,rtsirq;
+       int                     txirq,rxirq,rtsirq;
+       int                     have_rtscts:1;
 };
 
 /*
@@ -181,7 +182,7 @@ static void imx_start_tx(struct uart_port *port)
                imx_transmit_buffer(sport);
 }
 
-static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_rtsint(int irq, void *dev_id)
 {
        struct imx_port *sport = (struct imx_port *)dev_id;
        unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
@@ -197,7 +198,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_txint(int irq, void *dev_id)
 {
        struct imx_port *sport = (struct imx_port *)dev_id;
        struct circ_buf *xmit = &sport->port.info->xmit;
@@ -226,7 +227,7 @@ out:
        return IRQ_HANDLED;
 }
 
-static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_rxint(int irq, void *dev_id)
 {
        struct imx_port *sport = dev_id;
        unsigned int rx,flg,ignored = 0;
@@ -247,7 +248,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs)
                }
 
                if (uart_handle_sysrq_char
-                           (&sport->port, (unsigned char)rx, regs))
+                           (&sport->port, (unsigned char)rx))
                        goto ignore_char;
 
                if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) )
@@ -403,7 +404,7 @@ static int imx_startup(struct uart_port *port)
        if (retval) goto error_out2;
 
        retval = request_irq(sport->rtsirq, imx_rtsint,
-                            SA_TRIGGER_FALLING | SA_TRIGGER_RISING,
+                            IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                             DRIVER_NAME, sport);
        if (retval) goto error_out3;
 
@@ -458,8 +459,8 @@ static void imx_shutdown(struct uart_port *port)
 }
 
 static void
-imx_set_termios(struct uart_port *port, struct termios *termios,
-                  struct termios *old)
+imx_set_termios(struct uart_port *port, struct ktermios *termios,
+                  struct ktermios *old)
 {
        struct imx_port *sport = (struct imx_port *)port;
        unsigned long flags;
@@ -491,8 +492,12 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
                ucr2 = UCR2_SRST | UCR2_IRTS;
 
        if (termios->c_cflag & CRTSCTS) {
-               ucr2 &= ~UCR2_IRTS;
-               ucr2 |= UCR2_CTSC;
+               if( sport->have_rtscts ) {
+                       ucr2 &= ~UCR2_IRTS;
+                       ucr2 |= UCR2_CTSC;
+               } else {
+                       termios->c_cflag &= ~CRTSCTS;
+               }
        }
 
        if (termios->c_cflag & CSTOPB)
@@ -719,30 +724,16 @@ static void __init imx_init_ports(void)
                imx_ports[i].timer.function = imx_timeout;
                imx_ports[i].timer.data     = (unsigned long)&imx_ports[i];
        }
-
-       imx_gpio_mode(PC9_PF_UART1_CTS);
-       imx_gpio_mode(PC10_PF_UART1_RTS);
-       imx_gpio_mode(PC11_PF_UART1_TXD);
-       imx_gpio_mode(PC12_PF_UART1_RXD);
-       imx_gpio_mode(PB28_PF_UART2_CTS);
-       imx_gpio_mode(PB29_PF_UART2_RTS);
-
-       imx_gpio_mode(PB30_PF_UART2_TXD);
-       imx_gpio_mode(PB31_PF_UART2_RXD);
-
-#if 0 /* We don't need these, on the mx1 the _modem_ side of the uart
-       * is implemented.
-       */
-       imx_gpio_mode(PD7_AF_UART2_DTR);
-       imx_gpio_mode(PD8_AF_UART2_DCD);
-       imx_gpio_mode(PD9_AF_UART2_RI);
-       imx_gpio_mode(PD10_AF_UART2_DSR);
-#endif
-
-
 }
 
 #ifdef CONFIG_SERIAL_IMX_CONSOLE
+static void imx_console_putchar(struct uart_port *port, int ch)
+{
+       struct imx_port *sport = (struct imx_port *)port;
+       while ((UTS((u32)sport->port.membase) & UTS_TXFULL))
+               barrier();
+       URTX0((u32)sport->port.membase) = ch;
+}
 
 /*
  * Interrupts are disabled on entering
@@ -751,7 +742,7 @@ static void
 imx_console_write(struct console *co, const char *s, unsigned int count)
 {
        struct imx_port *sport = &imx_ports[co->index];
-       unsigned int old_ucr1, old_ucr2, i;
+       unsigned int old_ucr1, old_ucr2;
 
        /*
         *      First, save UCR1/2 and then disable interrupts
@@ -764,22 +755,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
                           & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
        UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
 
-       /*
-        *      Now, do each character
-        */
-       for (i = 0; i < count; i++) {
-
-               while ((UTS((u32)sport->port.membase) & UTS_TXFULL))
-                       barrier();
-
-               URTX0((u32)sport->port.membase) = s[i];
-
-               if (s[i] == '\n') {
-                       while ((UTS((u32)sport->port.membase) & UTS_TXFULL))
-                               barrier();
-                       URTX0((u32)sport->port.membase) = '\r';
-               }
-       }
+       uart_console_write(&sport->port, s, count, imx_console_putchar);
 
        /*
         *      Finally, wait for transmitter to become empty
@@ -911,7 +887,6 @@ static struct uart_driver imx_reg = {
        .owner          = THIS_MODULE,
        .driver_name    = DRIVER_NAME,
        .dev_name       = "ttySMX",
-       .devfs_name     = "ttsmx/",
        .major          = SERIAL_IMX_MAJOR,
        .minor          = MINOR_START,
        .nr             = ARRAY_SIZE(imx_ports),
@@ -940,7 +915,14 @@ static int serial_imx_resume(struct platform_device *dev)
 
 static int serial_imx_probe(struct platform_device *dev)
 {
+       struct imxuart_platform_data *pdata;
+
        imx_ports[dev->id].port.dev = &dev->dev;
+
+       pdata = (struct imxuart_platform_data *)dev->dev.platform_data;
+       if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
+               imx_ports[dev->id].have_rtscts = 1;
+
        uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
        platform_set_drvdata(dev, &imx_ports[dev->id]);
        return 0;