]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/serial/imx.c
[SERIAL] 8250_pci: Remove redundant assignment, and mark fallthrough.
[linux-2.6-omap-h63xx.git] / drivers / serial / imx.c
index 4e1e80adaf11f4baae5d24e42dcfaaf1be2e26b7..83c4c12165877c4e02b2449a63969dbdba05ab04 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
@@ -73,7 +73,7 @@ struct imx_port {
        struct uart_port        port;
        struct timer_list       timer;
        unsigned int            old_status;
-       int txirq,rxirq;
+       int txirq,rxirq,rtsirq;
 };
 
 /*
@@ -181,6 +181,22 @@ 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)
+{
+       struct imx_port *sport = (struct imx_port *)dev_id;
+       unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sport->port.lock, flags);
+
+       USR1((u32)sport->port.membase) = USR1_RTSD;
+       uart_handle_cts_change(&sport->port, !!val);
+       wake_up_interruptible(&sport->port.info->delta_msr_wait);
+
+       spin_unlock_irqrestore(&sport->port.lock, flags);
+       return IRQ_HANDLED;
+}
+
 static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct imx_port *sport = (struct imx_port *)dev_id;
@@ -383,18 +399,24 @@ static int imx_startup(struct uart_port *port)
         */
        retval = request_irq(sport->rxirq, imx_rxint, 0,
                             DRIVER_NAME, sport);
-       if (retval) goto error_out2;
+       if (retval) goto error_out1;
 
        retval = request_irq(sport->txirq, imx_txint, 0,
-                            "imx-uart", sport);
-       if (retval) goto error_out1;
+                            DRIVER_NAME, sport);
+       if (retval) goto error_out2;
+
+       retval = request_irq(sport->rtsirq, imx_rtsint, 0,
+                            DRIVER_NAME, sport);
+       if (retval) goto error_out3;
+       set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
 
        /*
         * Finally, clear and enable interrupts
         */
 
+       USR1((u32)sport->port.membase) = USR1_RTSD;
        UCR1((u32)sport->port.membase) |=
-                        (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+                        (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
 
        UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
        /*
@@ -406,10 +428,11 @@ static int imx_startup(struct uart_port *port)
 
        return 0;
 
-error_out1:
-       free_irq(sport->rxirq, sport);
-error_out2:
+error_out3:
        free_irq(sport->txirq, sport);
+error_out2:
+       free_irq(sport->rxirq, sport);
+error_out1:
        return retval;
 }
 
@@ -425,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
        /*
         * Free the interrupts
         */
+       free_irq(sport->rtsirq, sport);
        free_irq(sport->txirq, sport);
        free_irq(sport->rxirq, sport);
 
@@ -433,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
         */
 
        UCR1((u32)sport->port.membase) &=
-                        ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+                        ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
 }
 
 static void
@@ -523,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
         * disable interrupts and drain transmitter
         */
        old_ucr1 = UCR1((u32)sport->port.membase);
-       UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+       UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
 
        while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
                barrier();
@@ -644,6 +668,7 @@ static struct imx_port imx_ports[] = {
        {
        .txirq  = UART1_MINT_TX,
        .rxirq  = UART1_MINT_RX,
+       .rtsirq = UART1_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
                .iotype         = SERIAL_IO_MEM,
@@ -659,6 +684,7 @@ static struct imx_port imx_ports[] = {
        }, {
        .txirq  = UART2_MINT_TX,
        .rxirq  = UART2_MINT_RX,
+       .rtsirq = UART2_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
                .iotype         = SERIAL_IO_MEM,
@@ -738,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 
        UCR1((u32)sport->port.membase) =
                           (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
-                          & ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+                          & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
        UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
 
        /*
@@ -895,41 +921,39 @@ static struct uart_driver imx_reg = {
        .cons           = IMX_CONSOLE,
 };
 
-static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
 {
-        struct imx_port *sport = dev_get_drvdata(_dev);
+        struct imx_port *sport = platform_get_drvdata(dev);
 
-        if (sport && level == SUSPEND_DISABLE)
+        if (sport)
                 uart_suspend_port(&imx_reg, &sport->port);
 
         return 0;
 }
 
-static int serial_imx_resume(struct device *_dev, u32 level)
+static int serial_imx_resume(struct platform_device *dev)
 {
-        struct imx_port *sport = dev_get_drvdata(_dev);
+        struct imx_port *sport = platform_get_drvdata(dev);
 
-        if (sport && level == RESUME_ENABLE)
+        if (sport)
                 uart_resume_port(&imx_reg, &sport->port);
 
         return 0;
 }
 
-static int serial_imx_probe(struct device *_dev)
+static int serial_imx_probe(struct platform_device *dev)
 {
-       struct platform_device *dev = to_platform_device(_dev);
-
-       imx_ports[dev->id].port.dev = _dev;
+       imx_ports[dev->id].port.dev = &dev->dev;
        uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
-       dev_set_drvdata(_dev, &imx_ports[dev->id]);
+       platform_set_drvdata(dev, &imx_ports[dev->id]);
        return 0;
 }
 
-static int serial_imx_remove(struct device *_dev)
+static int serial_imx_remove(struct platform_device *dev)
 {
-       struct imx_port *sport = dev_get_drvdata(_dev);
+       struct imx_port *sport = platform_get_drvdata(dev);
 
-       dev_set_drvdata(_dev, NULL);
+       platform_set_drvdata(dev, NULL);
 
        if (sport)
                uart_remove_one_port(&imx_reg, &sport->port);
@@ -937,14 +961,15 @@ static int serial_imx_remove(struct device *_dev)
        return 0;
 }
 
-static struct device_driver serial_imx_driver = {
-        .name           = "imx-uart",
-        .bus            = &platform_bus_type,
+static struct platform_driver serial_imx_driver = {
         .probe          = serial_imx_probe,
         .remove         = serial_imx_remove,
 
        .suspend        = serial_imx_suspend,
        .resume         = serial_imx_resume,
+       .driver         = {
+               .name   = "imx-uart",
+       },
 };
 
 static int __init imx_serial_init(void)
@@ -959,7 +984,7 @@ static int __init imx_serial_init(void)
        if (ret)
                return ret;
 
-       ret = driver_register(&serial_imx_driver);
+       ret = platform_driver_register(&serial_imx_driver);
        if (ret != 0)
                uart_unregister_driver(&imx_reg);
 
@@ -969,6 +994,7 @@ static int __init imx_serial_init(void)
 static void __exit imx_serial_exit(void)
 {
        uart_unregister_driver(&imx_reg);
+       platform_driver_unregister(&serial_imx_driver);
 }
 
 module_init(imx_serial_init);