atmel_serial: use cpu_relax() when busy-waiting
[safe/jmp/linux-2.6] / drivers / serial / 68360serial.c
index 170c9d2..2aa6bfe 100644 (file)
@@ -20,7 +20,6 @@
  *     int rs_360_init(void);
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
@@ -394,7 +393,7 @@ static void rs_360_start(struct tty_struct *tty)
 static _INLINE_ void receive_chars(ser_info_t *info)
 {
        struct tty_struct *tty = info->tty;
-       unsigned char ch, *cp;
+       unsigned char ch, flag, *cp;
        /*int   ignored = 0;*/
        int     i;
        ushort  status;
@@ -438,24 +437,15 @@ static _INLINE_ void receive_chars(ser_info_t *info)
                cp = (char *)bdp->buf;
                status = bdp->status;
 
-               /* Check to see if there is room in the tty buffer for
-                * the characters in our BD buffer.  If not, we exit
-                * now, leaving the BD with the characters.  We'll pick
-                * them up again on the next receive interrupt (which could
-                * be a timeout).
-                */
-               if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE)
-                       break;
-
                while (i-- > 0) {
                        ch = *cp++;
-                       *tty->flip.char_buf_ptr = ch;
                        icount->rx++;
 
 #ifdef SERIAL_DEBUG_INTR
                        printk("DR%02x:%02x...", ch, status);
 #endif
-                       *tty->flip.flag_buf_ptr = 0;
+                       flag = TTY_NORMAL;
+
                        if (status & (BD_SC_BR | BD_SC_FR |
                                       BD_SC_PR | BD_SC_OV)) {
                                /*
@@ -490,30 +480,18 @@ static _INLINE_ void receive_chars(ser_info_t *info)
                                        if (info->flags & ASYNC_SAK)
                                                do_SAK(tty);
                                } else if (status & BD_SC_PR)
-                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                else if (status & BD_SC_FR)
-                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
-                               if (status & BD_SC_OV) {
-                                       /*
-                                        * Overrun is special, since it's
-                                        * reported immediately, and doesn't
-                                        * affect the current character
-                                        */
-                                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                               tty->flip.count++;
-                                               tty->flip.flag_buf_ptr++;
-                                               tty->flip.char_buf_ptr++;
-                                               *tty->flip.flag_buf_ptr =
-                                                               TTY_OVERRUN;
-                                       }
-                               }
+                                       flag = TTY_FRAME;
                        }
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               break;
-
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flag);
+                       if (status & BD_SC_OV)
+                               /*
+                                * Overrun is special, since it's
+                                * reported immediately, and doesn't
+                                * affect the current character
+                                */
+                               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
 
                /* This BD is ready to be used again.  Clear status.
@@ -530,7 +508,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
 
        info->rx_cur = (QUICC_BD *)bdp;
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void receive_break(ser_info_t *info)
@@ -541,13 +519,8 @@ static _INLINE_ void receive_break(ser_info_t *info)
        /* Check to see if there is room in the tty buffer for
         * the break.  If not, we exit now, losing the break.  FIXME
         */
-       if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE)
-               return;
-       *(tty->flip.flag_buf_ptr++) = TTY_BREAK;
-       *(tty->flip.char_buf_ptr++) = 0;
-       tty->flip.count++;
-
-       schedule_work(&tty->flip.work);
+       tty_insert_flip_char(tty, 0, TTY_BREAK);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
@@ -639,7 +612,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
  * This is the serial driver's interrupt routine for a single port
  */
 /* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */
-static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+static void rs_360_interrupt(int vec, void *dev_id)
 {
        u_char  events;
        int     idx;
@@ -647,7 +620,7 @@ static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp)
        volatile struct smc_regs *smcp;
        volatile struct scc_regs *sccp;
        
-       info = (ser_info_t *)dev_id;
+       info = dev_id;
 
        idx = PORT_NUM(info->state->smc_scc_num);
        if (info->state->smc_scc_num & NUM_IS_SCC) {
@@ -961,8 +934,6 @@ static void change_speed(ser_info_t *info)
        /*
         * Set up parity check flag
         */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
        info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
        if (I_INPCK(info->tty))
                info->read_status_mask |= BD_SC_FR | BD_SC_PR;
@@ -1550,15 +1521,10 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
 
 /* FIX UP modem control here someday......
 */
-static void rs_360_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
        ser_info_t *info = (ser_info_t *)tty->driver_data;
 
-       if (   (tty->termios->c_cflag == old_termios->c_cflag)
-           && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
-               == RELEVANT_IFLAG(old_termios->c_iflag)))
-         return;
-
        change_speed(info);
 
 #ifdef modem_control
@@ -2451,7 +2417,7 @@ long console_360_init(long kmem_start, long kmem_end)
 */
 static int     baud_idx;
 
-static struct tty_operations rs_360_ops = {
+static const struct tty_operations rs_360_ops = {
        .owner = THIS_MODULE,
        .open = rs_360_open,
        .close = rs_360_close,