gpiolib: fix poll(2) support reconfigure on sysfs polarity change
[safe/jmp/linux-2.6] / drivers / serial / pxa.c
index 6443b7f..56ee082 100644 (file)
@@ -438,6 +438,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
+       unsigned int dll;
 
        switch (termios->c_cflag & CSIZE) {
        case CS5:
@@ -534,10 +535,18 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
        else
                up->mcr &= ~UART_MCR_AFE;
 
-       serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+       serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
        serial_out(up, UART_DLL, quot & 0xff);          /* LS of divisor */
+
+       /*
+        * work around Errata #75 according to Intel(R) PXA27x Processor Family
+        * Specification Update (Nov 2005)
+        */
+       dll = serial_in(up, UART_DLL);
+       WARN_ON(dll != (quot & 0xff));
+
        serial_out(up, UART_DLM, quot >> 8);            /* MS of divisor */
-       serial_out(up, UART_LCR, cval);         /* reset DLAB */
+       serial_out(up, UART_LCR, cval);                 /* reset DLAB */
        up->lcr = cval;                                 /* Save LCR */
        serial_pxa_set_mctrl(&up->port, up->port.mctrl);
        serial_out(up, UART_FCR, fcr);
@@ -726,9 +735,10 @@ static struct uart_driver serial_pxa_reg = {
        .cons           = PXA_CONSOLE,
 };
 
-static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM
+static int serial_pxa_suspend(struct device *dev)
 {
-        struct uart_pxa_port *sport = platform_get_drvdata(dev);
+        struct uart_pxa_port *sport = dev_get_drvdata(dev);
 
         if (sport)
                 uart_suspend_port(&serial_pxa_reg, &sport->port);
@@ -736,9 +746,9 @@ static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state)
         return 0;
 }
 
-static int serial_pxa_resume(struct platform_device *dev)
+static int serial_pxa_resume(struct device *dev)
 {
-        struct uart_pxa_port *sport = platform_get_drvdata(dev);
+        struct uart_pxa_port *sport = dev_get_drvdata(dev);
 
         if (sport)
                 uart_resume_port(&serial_pxa_reg, &sport->port);
@@ -746,6 +756,12 @@ static int serial_pxa_resume(struct platform_device *dev)
         return 0;
 }
 
+static const struct dev_pm_ops serial_pxa_pm_ops = {
+       .suspend        = serial_pxa_suspend,
+       .resume         = serial_pxa_resume,
+};
+#endif
+
 static int serial_pxa_probe(struct platform_device *dev)
 {
        struct uart_pxa_port *sport;
@@ -825,11 +841,12 @@ static struct platform_driver serial_pxa_driver = {
         .probe          = serial_pxa_probe,
         .remove         = serial_pxa_remove,
 
-       .suspend        = serial_pxa_suspend,
-       .resume         = serial_pxa_resume,
        .driver         = {
                .name   = "pxa2xx-uart",
                .owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+               .pm     = &serial_pxa_pm_ops,
+#endif
        },
 };