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 / mcfserial.c
index 8c40167..8cbbb95 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/segment.h>
 #include <asm/semaphore.h>
 #include <asm/delay.h>
 #include <asm/coldfire.h>
@@ -58,16 +57,18 @@ struct timer_list mcfrs_timer_struct;
  *     keep going.  Perhaps one day the cflag settings for the
  *     console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#if defined(CONFIG_HW_FEITH)
+#define        CONSOLE_BAUD_RATE       38400
+#define        DEFAULT_CBAUD           B38400
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
+#define CONSOLE_BAUD_RATE      115200
+#define DEFAULT_CBAUD          B115200
+#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+      defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
 #define        CONSOLE_BAUD_RATE       19200
 #define        DEFAULT_CBAUD           B19200
 #endif
 
-#if defined(CONFIG_HW_FEITH)
-  #define      CONSOLE_BAUD_RATE       38400
-  #define      DEFAULT_CBAUD           B38400
-#endif
-
 #ifndef CONSOLE_BAUD_RATE
 #define        CONSOLE_BAUD_RATE       9600
 #define        DEFAULT_CBAUD           B9600
@@ -91,7 +92,8 @@ static struct tty_driver *mcfrs_serial_driver;
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define        IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
 #else
 #define        IRQBASE 73
@@ -307,7 +309,7 @@ static inline void receive_chars(struct mcf_serial *info)
 {
        volatile unsigned char  *uartp;
        struct tty_struct       *tty = info->tty;
-       unsigned char           status, ch;
+       unsigned char           status, ch, flag;
 
        if (!tty)
                return;
@@ -315,10 +317,6 @@ static inline void receive_chars(struct mcf_serial *info)
        uartp = info->addr;
 
        while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) {
-
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
-
                ch = uartp[MCFUART_URB];
                info->stats.rx++;
 
@@ -329,32 +327,26 @@ static inline void receive_chars(struct mcf_serial *info)
                }
 #endif
 
-               tty->flip.count++;
+               flag = TTY_NORMAL;
                if (status & MCFUART_USR_RXERR) {
                        uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;
                        if (status & MCFUART_USR_RXBREAK) {
                                info->stats.rxbreak++;
-                               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (status & MCFUART_USR_RXPARITY) {
                                info->stats.rxparity++;
-                               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+                               flag = TTY_PARITY;
                        } else if (status & MCFUART_USR_RXOVERRUN) {
                                info->stats.rxoverrun++;
-                               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+                               flag = TTY_OVERRUN;
                        } else if (status & MCFUART_USR_RXFRAMING) {
                                info->stats.rxframing++;
-                               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-                       } else {
-                               /* This should never happen... */
-                               *tty->flip.flag_buf_ptr++ = 0;
+                               flag = TTY_FRAME;
                        }
-               } else {
-                       *tty->flip.flag_buf_ptr++ = 0;
                }
-               *tty->flip.char_buf_ptr++ = ch;
+               tty_insert_flip_char(tty, ch, flag);
        }
-
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
        return;
 }
 
@@ -1511,7 +1503,7 @@ static void mcfrs_irqinit(struct mcf_serial *info)
        *portp = (*portp & ~0x000000ff) | 0x00000055;
        portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT);
        *portp = (*portp & ~0x000003fc) | 0x000002a8;
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
        volatile unsigned char *icrp, *uartp;
        volatile unsigned long *imrp;
 
@@ -1519,11 +1511,40 @@ static void mcfrs_irqinit(struct mcf_serial *info)
 
        icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
                MCFINTC_ICR0 + MCFINT_UART0 + info->line);
-       *icrp = 0x33; /* UART0 with level 6, priority 3 */
+       *icrp = 0x30 + info->line; /* level 6, line based priority */
 
        imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
                MCFINTC_IMRL);
        *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#elif defined(CONFIG_M520x)
+       volatile unsigned char *icrp, *uartp;
+       volatile unsigned long *imrp;
+
+       uartp = info->addr;
+
+       icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+               MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+       *icrp = 0x03;
+
+       imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+               MCFINTC_IMRL);
+       *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+       if (info->line < 2) {
+               unsigned short *uart_par;
+               uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               if (info->line == 0)
+                       *uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD0
+                                 | MCF_GPIO_PAR_UART_PAR_URXD0;
+               else if (info->line == 1)
+                       *uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD1
+                                 | MCF_GPIO_PAR_UART_PAR_URXD1;
+               } else if (info->line == 2) {
+                       unsigned char *feci2c_par;
+                       feci2c_par = (unsigned char *)(MCF_IPSBAR +  MCF_GPIO_PAR_FECI2C);
+                       *feci2c_par &= ~0x0F;
+                       *feci2c_par |=  MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
+                                   | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+               }
 #else
        volatile unsigned char  *icrp, *uartp;