linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / serial / 68328serial.c
index 6dd5224..7f0f35a 100644 (file)
 #include <linux/keyboard.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/segment.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
 
@@ -142,7 +143,6 @@ static int m68328_console_cbaud   = DEFAULT_CBAUD;
  * memory if large numbers of serial ports are open.
  */
 static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
-DECLARE_MUTEX(tmp_buf_sem);
 
 static inline int serial_paranoia_check(struct m68k_serial *info,
                                        char *name, const char *routine)
@@ -293,7 +293,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
 {
        struct tty_struct *tty = info->tty;
        m68328_uart *uart = &uart_addr[info->line];
-       unsigned char ch;
+       unsigned char ch, flag;
 
        /*
         * This do { } while() loop will get ALL chars out of Rx FIFO 
@@ -315,7 +315,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
 /*                             show_net_buffers(); */
                                return;
                        } else if (ch == 0x12) { /* ^R */
-                               machine_restart(NULL);
+                               emergency_restart();
                                return;
 #endif /* CONFIG_MAGIC_SYSRQ */
                        }
@@ -331,31 +331,29 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
                /*
                 * Make sure that we do not overflow the buffer
                 */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       schedule_work(&tty->flip.work);
+               if (tty_request_buffer_room(tty, 1) == 0) {
+                       tty_schedule_flip(tty);
                        return;
                }
 
+               flag = TTY_NORMAL;
+
                if(rx & URX_PARITY_ERROR) {
-                       *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+                       flag = TTY_PARITY;
                        status_handle(info, rx);
                } else if(rx & URX_OVRUN) {
-                       *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+                       flag = TTY_OVERRUN;
                        status_handle(info, rx);
                } else if(rx & URX_FRAME_ERROR) {
-                       *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+                       flag = TTY_FRAME;
                        status_handle(info, rx);
-               } else {
-                       *tty->flip.flag_buf_ptr++ = 0; /* XXX */
                }
-                *tty->flip.char_buf_ptr++ = ch;
-               tty->flip.count++;
-
+               tty_insert_flip_char(tty, ch, flag);
 #ifndef CONFIG_XCOPILOT_BUGS
        } while((rx = uart->urx.w) & URX_DATA_READY);
 #endif
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 
 clear_and_exit:
        return;
@@ -757,7 +755,7 @@ static void rs_flush_chars(struct tty_struct *tty)
 
 extern void console_printn(const char * b, int count);
 
-static int rs_write(struct tty_struct * tty, int from_user,
+static int rs_write(struct tty_struct * tty,
                    const unsigned char *buf, int count)
 {
        int     c, total = 0;
@@ -779,15 +777,7 @@ static int rs_write(struct tty_struct * tty, int from_user,
                if (c <= 0)
                        break;
 
-               if (from_user) {
-                       down(&tmp_buf_sem);
-                       copy_from_user(tmp_buf, buf, c);
-                       c = min_t(int, c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-                                      SERIAL_XMIT_SIZE - info->xmit_head));
-                       memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-                       up(&tmp_buf_sem);
-               } else
-                       memcpy(info->xmit_buf + info->xmit_head, buf, c);
+               memcpy(info->xmit_buf + info->xmit_head, buf, c);
                info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
                info->xmit_cnt += c;
                restore_flags(flags);
@@ -999,18 +989,17 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break(        struct m68k_serial * info, int duration)
+static void send_break(struct m68k_serial * info, unsigned int duration)
 {
        m68328_uart *uart = &uart_addr[info->line];
         unsigned long flags;
         if (!info->port)
                 return;
-        current->state = TASK_INTERRUPTIBLE;
         save_flags(flags);
         cli();
 #ifdef USE_INTS        
        uart->utx.w |= UTX_SEND_BREAK;
-        schedule_timeout(duration);
+       msleep_interruptible(duration);
        uart->utx.w &= ~UTX_SEND_BREAK;
 #endif         
         restore_flags(flags);
@@ -1040,14 +1029,14 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                                return retval;
                        tty_wait_until_sent(tty, 0);
                        if (!arg)
-                               send_break(info, HZ/4); /* 1/4 second */
+                               send_break(info, 250);  /* 1/4 second */
                        return 0;
                case TCSBRKP:   /* support for POSIX tcsendbreak() */
                        retval = tty_check_change(tty);
                        if (retval)
                                return retval;
                        tty_wait_until_sent(tty, 0);
-                       send_break(info, arg ? arg*(HZ/10) : HZ/4);
+                       send_break(info, arg ? arg*(100) : 250);
                        return 0;
                case TIOCGSOFTCAR:
                        error = put_user(C_CLOCAL(tty) ? 1 : 0,
@@ -1062,28 +1051,23 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                                 (arg ? CLOCAL : 0));
                        return 0;
                case TIOCGSERIAL:
-                       error = verify_area(VERIFY_WRITE, (void *) arg,
-                                               sizeof(struct serial_struct));
-                       if (error)
-                               return error;
-                       return get_serial_info(info,
+                       if (access_ok(VERIFY_WRITE, (void *) arg,
+                                               sizeof(struct serial_struct)))
+                               return get_serial_info(info,
                                               (struct serial_struct *) arg);
+                       return -EFAULT;
                case TIOCSSERIAL:
                        return set_serial_info(info,
                                               (struct serial_struct *) arg);
                case TIOCSERGETLSR: /* Get line status register */
-                       error = verify_area(VERIFY_WRITE, (void *) arg,
-                               sizeof(unsigned int));
-                       if (error)
-                               return error;
-                       else
-                           return get_lsr_info(info, (unsigned int *) arg);
-
+                       if (access_ok(VERIFY_WRITE, (void *) arg,
+                                               sizeof(unsigned int));
+                               return get_lsr_info(info, (unsigned int *) arg);
+                       return -EFAULT;
                case TIOCSERGSTRUCT:
-                       error = verify_area(VERIFY_WRITE, (void *) arg,
-                                               sizeof(struct m68k_serial));
-                       if (error)
-                               return error;
+                       if (!access_ok(VERIFY_WRITE, (void *) arg,
+                                               sizeof(struct m68k_serial)))
+                               return -EFAULT;
                        copy_to_user((struct m68k_serial *) arg,
                                    info, sizeof(struct m68k_serial));
                        return 0;
@@ -1197,8 +1181,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 #endif 
        if (info->blocked_open) {
                if (info->close_delay) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(info->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(info->close_delay));
                }
                wake_up_interruptible(&info->open_wait);
        }
@@ -1358,7 +1341,7 @@ static void show_serial_version(void)
        printk("MC68328 serial driver version 1.00\n");
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 /* Serial Power management
  *  The console (currently fixed at line 0) is a special case for power
  *  management because the kernel is so chatty. The console will be 
@@ -1408,7 +1391,7 @@ void startup_console(void)
        struct m68k_serial *info = &m68k_soft[0];
        startup(info);
 }
-#endif
+#endif /* CONFIG_PM_LEGACY */
 
 
 static struct tty_operations rs_ops = {
@@ -1501,7 +1484,7 @@ rs68328_init(void)
                            IRQ_FLG_STD,
                            "M68328_UART", NULL))
                 panic("Unable to attach 68328 serial interrupt\n");
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
            serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
            if (serial_pm[i])
                    serial_pm[i]->data = info;
@@ -1511,23 +1494,6 @@ rs68328_init(void)
        return 0;
 }
 
-
-
-/*
- * register_serial and unregister_serial allows for serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-/* SPARC: Unused at this time, just here to make things link. */
-int register_serial(struct serial_struct *req)
-{
-       return -1;
-}
-
-void unregister_serial(int line)
-{
-       return;
-}
-       
 module_init(rs68328_init);