Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / serial / mpc52xx_uart.c
index 2a5cf17..6459edc 100644 (file)
  * by the bootloader or in the platform init code.
  *
  * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyS0, PSC2 to /dev/ttyS1 and so
- * on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly for
- * the console code : without this 1:1 mapping, at early boot time, when we are
- * parsing the kernel args console=ttyS?, we wouldn't know wich PSC it will be
- * mapped to.
+ * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
+ * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
+ * fpr the console code : without this 1:1 mapping, at early boot time, when we
+ * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it
+ * will be mapped to.
  */
 
 #include <linux/config.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 
 
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_PSC_MAJOR       204
+#define SERIAL_PSC_MINOR       148
+
 
 #define ISR_PASS_LIMIT 256     /* Max number of iteration in the interrupt */
 
@@ -119,7 +123,7 @@ mpc52xx_uart_get_mctrl(struct uart_port *port)
 }
 
 static void 
-mpc52xx_uart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+mpc52xx_uart_stop_tx(struct uart_port *port)
 {
        /* port->lock taken by caller */
        port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
@@ -127,7 +131,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port, unsigned int tty_stop)
 }
 
 static void 
-mpc52xx_uart_start_tx(struct uart_port *port, unsigned int tty_start)
+mpc52xx_uart_start_tx(struct uart_port *port)
 {
        /* port->lock taken by caller */
        port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
@@ -401,17 +405,13 @@ static inline int
 mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
 {
        struct tty_struct *tty = port->info->tty;
-       unsigned char ch;
+       unsigned char ch, flag;
        unsigned short status;
 
        /* While we can read, do so ! */
        while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) &
                MPC52xx_PSC_SR_RXRDY) {
 
-               /* If we are full, just stop reading */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
-               
                /* Get the char */
                ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8);
 
@@ -424,45 +424,35 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
 #endif
 
                /* Store it */
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = 0;
+
+               flag = TTY_NORMAL;
                port->icount.rx++;
        
                if ( status & (MPC52xx_PSC_SR_PE |
                               MPC52xx_PSC_SR_FE |
-                              MPC52xx_PSC_SR_RB |
-                              MPC52xx_PSC_SR_OE) ) {
+                              MPC52xx_PSC_SR_RB) ) {
                        
                        if (status & MPC52xx_PSC_SR_RB) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                                uart_handle_break(port);
                        } else if (status & MPC52xx_PSC_SR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (status & MPC52xx_PSC_SR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-                       if (status & MPC52xx_PSC_SR_OE) {
-                               /*
-                                * Overrun is special, since it's
-                                * reported immediately, and doesn't
-                                * affect the current character
-                                */
-                               if (tty->flip.count < (TTY_FLIPBUF_SIZE-1)) {
-                                       tty->flip.flag_buf_ptr++;
-                                       tty->flip.char_buf_ptr++;
-                                       tty->flip.count++;
-                               }
-                               *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       }
+                               flag = TTY_FRAME;
 
                        /* Clear error condition */
                        out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT);
 
                }
-
-               tty->flip.char_buf_ptr++;
-               tty->flip.flag_buf_ptr++;
-               tty->flip.count++;
-
+               tty_insert_flip_char(tty, ch, flag);
+               if (status & MPC52xx_PSC_SR_OE) {
+                       /*
+                        * Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               }
        }
 
        tty_flip_buffer_push(tty);
@@ -485,7 +475,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
 
        /* Nothing to do ? */
        if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-               mpc52xx_uart_stop_tx(port,0);
+               mpc52xx_uart_stop_tx(port);
                return 0;
        }
 
@@ -504,7 +494,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
 
        /* Maybe we're done after all */
        if (uart_circ_empty(xmit)) {
-               mpc52xx_uart_stop_tx(port,0);
+               mpc52xx_uart_stop_tx(port);
                return 0;
        }
 
@@ -613,15 +603,14 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
                udelay(1);
 
        /* Write all the chars */
-       for ( i=0 ; i<count ; i++ ) {
-       
-               /* Send the char */
-               out_8(&psc->mpc52xx_psc_buffer_8, *s);
-
+       for (i = 0; i < count; i++, s++) {
                /* Line return handling */
-               if ( *s++ == '\n' )
+               if (*s == '\n')
                        out_8(&psc->mpc52xx_psc_buffer_8, '\r');
                
+               /* Send the char */
+               out_8(&psc->mpc52xx_psc_buffer_8, *s);
+
                /* Wait the TX buffer to be empty */
                j = 20000;      /* Maximum wait */      
                while (!(in_be16(&psc->mpc52xx_psc_status) & 
@@ -668,15 +657,15 @@ mpc52xx_console_setup(struct console *co, char *options)
 }
 
 
-extern struct uart_driver mpc52xx_uart_driver;
+static struct uart_driver mpc52xx_uart_driver;
 
 static struct console mpc52xx_console = {
-       .name   = "ttyS",
+       .name   = "ttyPSC",
        .write  = mpc52xx_console_write,
        .device = uart_console_device,
        .setup  = mpc52xx_console_setup,
        .flags  = CON_PRINTBUFFER,
-       .index  = -1,   /* Specified on the cmdline (e.g. console=ttyS0 ) */
+       .index  = -1,   /* Specified on the cmdline (e.g. console=ttyPSC0 ) */
        .data   = &mpc52xx_uart_driver,
 };
 
@@ -703,10 +692,10 @@ console_initcall(mpc52xx_console_init);
 static struct uart_driver mpc52xx_uart_driver = {
        .owner          = THIS_MODULE,
        .driver_name    = "mpc52xx_psc_uart",
-       .dev_name       = "ttyS",
-       .devfs_name     = "ttyS",
-       .major          = TTY_MAJOR,
-       .minor          = 64,
+       .dev_name       = "ttyPSC",
+       .devfs_name     = "ttyPSC",
+       .major          = SERIAL_PSC_MAJOR,
+       .minor          = SERIAL_PSC_MINOR,
        .nr             = MPC52xx_PSC_MAXNUM,
        .cons           = MPC52xx_PSC_CONSOLE,
 };
@@ -717,16 +706,15 @@ static struct uart_driver mpc52xx_uart_driver = {
 /* ======================================================================== */
 
 static int __devinit
-mpc52xx_uart_probe(struct device *dev)
+mpc52xx_uart_probe(struct platform_device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct resource *res = pdev->resource;
+       struct resource *res = dev->resource;
 
        struct uart_port *port = NULL;
        int i, idx, ret;
 
        /* Check validity & presence */
-       idx = pdev->id;
+       idx = dev->id;
        if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
                return -EINVAL;
 
@@ -749,7 +737,7 @@ mpc52xx_uart_probe(struct device *dev)
        port->ops       = &mpc52xx_uart_ops;
 
        /* Search for IRQ and mapbase */
-       for (i=0 ; i<pdev->num_resources ; i++, res++) {
+       for (i=0 ; i<dev->num_resources ; i++, res++) {
                if (res->flags & IORESOURCE_MEM)
                        port->mapbase = res->start;
                else if (res->flags & IORESOURCE_IRQ)
@@ -761,17 +749,17 @@ mpc52xx_uart_probe(struct device *dev)
        /* Add the port to the uart sub-system */
        ret = uart_add_one_port(&mpc52xx_uart_driver, port);
        if (!ret)
-               dev_set_drvdata(dev, (void*)port);
+               platform_set_drvdata(dev, (void*)port);
 
        return ret;
 }
 
 static int
-mpc52xx_uart_remove(struct device *dev)
+mpc52xx_uart_remove(struct platform_device *dev)
 {
-       struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
 
-       dev_set_drvdata(dev, NULL);
+       platform_set_drvdata(dev, NULL);
 
        if (port)
                uart_remove_one_port(&mpc52xx_uart_driver, port);
@@ -781,37 +769,38 @@ mpc52xx_uart_remove(struct device *dev)
 
 #ifdef CONFIG_PM
 static int
-mpc52xx_uart_suspend(struct device *dev, u32 state, u32 level)
+mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
 {
-       struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
 
-       if (sport && level == SUSPEND_DISABLE)
+       if (sport)
                uart_suspend_port(&mpc52xx_uart_driver, port);
 
        return 0;
 }
 
 static int
-mpc52xx_uart_resume(struct device *dev, u32 level)
+mpc52xx_uart_resume(struct platform_device *dev)
 {
-       struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
 
-       if (port && level == RESUME_ENABLE)
+       if (port)
                uart_resume_port(&mpc52xx_uart_driver, port);
 
        return 0;
 }
 #endif
 
-static struct device_driver mpc52xx_uart_platform_driver = {
-       .name           = "mpc52xx-psc",
-       .bus            = &platform_bus_type,
+static struct platform_driver mpc52xx_uart_platform_driver = {
        .probe          = mpc52xx_uart_probe,
        .remove         = mpc52xx_uart_remove,
 #ifdef CONFIG_PM
        .suspend        = mpc52xx_uart_suspend,
        .resume         = mpc52xx_uart_resume,
 #endif
+       .driver         = {
+               .name   = "mpc52xx-psc",
+       },
 };
 
 
@@ -828,7 +817,7 @@ mpc52xx_uart_init(void)
 
        ret = uart_register_driver(&mpc52xx_uart_driver);
        if (ret == 0) {
-               ret = driver_register(&mpc52xx_uart_platform_driver);
+               ret = platform_driver_register(&mpc52xx_uart_platform_driver);
                if (ret)
                        uart_unregister_driver(&mpc52xx_uart_driver);
        }
@@ -839,7 +828,7 @@ mpc52xx_uart_init(void)
 static void __exit
 mpc52xx_uart_exit(void)
 {
-       driver_unregister(&mpc52xx_uart_platform_driver);
+       platform_driver_unregister(&mpc52xx_uart_platform_driver);
        uart_unregister_driver(&mpc52xx_uart_driver);
 }