Pull error-inject into release branch
[powerpc.git] / drivers / serial / mcfserial.c
index 00d7859..99af084 100644 (file)
@@ -60,7 +60,8 @@ struct timer_list mcfrs_timer_struct;
 #if defined(CONFIG_HW_FEITH)
 #define        CONSOLE_BAUD_RATE       38400
 #define        DEFAULT_CBAUD           B38400
-#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || defined(CONFIG_M5329EVB)
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \
+      defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO)
 #define CONSOLE_BAUD_RATE      115200
 #define DEFAULT_CBAUD          B115200
 #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
@@ -109,12 +110,30 @@ static struct mcf_serial mcfrs_table[] = {
                .irq = IRQBASE,
                .flags = ASYNC_BOOT_AUTOCONF,
        },
+#ifdef MCFUART_BASE2
        {  /* ttyS1 */
                .magic = 0,
                .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2),
                .irq = IRQBASE+1,
                .flags = ASYNC_BOOT_AUTOCONF,
        },
+#endif
+#ifdef MCFUART_BASE3
+       {  /* ttyS2 */
+               .magic = 0,
+               .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3),
+               .irq = IRQBASE+2,
+               .flags = ASYNC_BOOT_AUTOCONF,
+       },
+#endif
+#ifdef MCFUART_BASE4
+       {  /* ttyS3 */
+               .magic = 0,
+               .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4),
+               .irq = IRQBASE+3,
+               .flags = ASYNC_BOOT_AUTOCONF,
+       },
+#endif
 };
 
 
@@ -385,7 +404,7 @@ static inline void transmit_chars(struct mcf_serial *info)
 /*
  * This is the serial driver's generic interrupt routine
  */
-irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
 {
        struct mcf_serial       *info;
        unsigned char           isr;
@@ -406,15 +425,13 @@ irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  * -------------------------------------------------------------------
  */
 
-static void mcfrs_offintr(void *private)
+static void mcfrs_offintr(struct work_struct *work)
 {
-       struct mcf_serial       *info = (struct mcf_serial *) private;
-       struct tty_struct       *tty;
+       struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
+       struct tty_struct *tty = info->tty;
        
-       tty = info->tty;
-       if (!tty)
-               return;
-       tty_wakeup(tty);
+       if (tty)
+               tty_wakeup(tty);
 }
 
 
@@ -478,16 +495,13 @@ static void mcfrs_timer(void)
  *     do_serial_hangup() -> tty->hangup() -> mcfrs_hangup()
  * 
  */
-static void do_serial_hangup(void *private)
+static void do_serial_hangup(struct work_struct *work)
 {
-       struct mcf_serial       *info = (struct mcf_serial *) private;
-       struct tty_struct       *tty;
+       struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
+       struct tty_struct *tty = info->tty;
        
-       tty = info->tty;
-       if (!tty)
-               return;
-
-       tty_hangup(tty);
+       if (tty)
+               tty_hangup(tty);
 }
 
 static int startup(struct mcf_serial * info)
@@ -838,7 +852,7 @@ static void mcfrs_throttle(struct tty_struct * tty)
 #ifdef SERIAL_DEBUG_THROTTLE
        char    buf[64];
        
-       printk("throttle %s: %d....\n", _tty_name(tty, buf),
+       printk("throttle %s: %d....\n", tty_name(tty, buf),
               tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -857,7 +871,7 @@ static void mcfrs_unthrottle(struct tty_struct * tty)
 #ifdef SERIAL_DEBUG_THROTTLE
        char    buf[64];
        
-       printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+       printk("unthrottle %s: %d....\n", tty_name(tty, buf),
               tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -1113,7 +1127,7 @@ static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
        return 0;
 }
 
-static void mcfrs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
        struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
 
@@ -1516,6 +1530,29 @@ static void mcfrs_irqinit(struct mcf_serial *info)
        imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
                MCFINTC_IMRL);
        *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#if defined(CONFIG_M527x)
+       {
+               /*
+                * External Pin Mask Setting & Enable External Pin for Interface
+                * mrcbis@aliceposta.it
+                */
+               u16 *serpin_enable_mask;
+               serpin_enable_mask = (u16 *) (MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               if (info->line == 0)
+                       *serpin_enable_mask |= UART0_ENABLE_MASK;
+               else if (info->line == 1)
+                       *serpin_enable_mask |= UART1_ENABLE_MASK;
+               else if (info->line == 2)
+                       *serpin_enable_mask |= UART2_ENABLE_MASK;
+       }
+#endif
+#if defined(CONFIG_M528x)
+       /* make sure PUAPAR is set for UART0 and UART1 */
+       if (info->line < 2) {
+               volatile unsigned char *portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR);
+               *portp |= (0x03 << (info->line * 2));
+       }
+#endif
 #elif defined(CONFIG_M520x)
        volatile unsigned char *icrp, *uartp;
        volatile unsigned long *imrp;
@@ -1713,7 +1750,7 @@ mcfrs_init(void)
        /* Initialize the tty_driver structure */
        mcfrs_serial_driver->owner = THIS_MODULE;
        mcfrs_serial_driver->name = "ttyS";
-       mcfrs_serial_driver->driver_name = "serial";
+       mcfrs_serial_driver->driver_name = "mcfserial";
        mcfrs_serial_driver->major = TTY_MAJOR;
        mcfrs_serial_driver->minor_start = 64;
        mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -1748,8 +1785,8 @@ mcfrs_init(void)
                info->event = 0;
                info->count = 0;
                info->blocked_open = 0;
-               INIT_WORK(&info->tqueue, mcfrs_offintr, info);
-               INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
+               INIT_WORK(&info->tqueue, mcfrs_offintr);
+               INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
                init_waitqueue_head(&info->open_wait);
                init_waitqueue_head(&info->close_wait);
 
@@ -1797,10 +1834,23 @@ void mcfrs_init_console(void)
        uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
        uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
 
+#ifdef CONFIG_M5272
+{
+       /*
+        * For the MCF5272, also compute the baudrate fraction.
+        */
+       int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud);
+       fraction *= 16;
+       fraction /= (32 * mcfrs_console_baud);
+       uartp[MCFUART_UFPD] = (fraction & 0xf);         /* set fraction */
+       clk = (MCF_BUSCLK / mcfrs_console_baud) / 32;
+}
+#else
        clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */
+#endif
+
        uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8;  /* set msb baud */
        uartp[MCFUART_UBG2] = (clk & 0xff);  /* set lsb baud */
-
        uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
        uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;