X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fserial%2F68328serial.c;fp=drivers%2Fserial%2F68328serial.c;h=cad426c9711e970d0b7d62718bf894b7ca54536c;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=7f0f35a05dcac35e30a05cce2f962ccf7e0510e6;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 7f0f35a05..cad426c97 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -101,8 +100,6 @@ struct tty_driver *serial_driver; #define RS_ISR_PASS_LIMIT 256 -#define _INLINE_ inline - static void change_speed(struct m68k_serial *info); /* @@ -133,17 +130,6 @@ static int m68328_console_baud = CONSOLE_BAUD_RATE; static int m68328_console_cbaud = DEFAULT_CBAUD; -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the memcpy_fromfs blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ - static inline int serial_paranoia_check(struct m68k_serial *info, char *name, const char *routine) { @@ -213,16 +199,16 @@ static void rs_stop(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_stop")) return; - save_flags(flags); cli(); + local_irq_save(flags); uart->ustcnt &= ~USTCNT_TXEN; - restore_flags(flags); + local_irq_restore(flags); } static void rs_put_char(char ch) { int flags, loops = 0; - save_flags(flags); cli(); + local_irq_save(flags); while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { loops++; @@ -231,7 +217,7 @@ static void rs_put_char(char ch) UTX_TXDATA = ch; udelay(5); - restore_flags(flags); + local_irq_restore(flags); } static void rs_start(struct tty_struct *tty) @@ -243,7 +229,7 @@ static void rs_start(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_start")) return; - save_flags(flags); cli(); + local_irq_save(flags); if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { #ifdef USE_INTS uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; @@ -251,7 +237,7 @@ static void rs_start(struct tty_struct *tty) uart->ustcnt |= USTCNT_TXEN; #endif } - restore_flags(flags); + local_irq_restore(flags); } /* Drop into either the boot monitor or kadb upon receiving a break @@ -262,7 +248,7 @@ static void batten_down_hatches(void) /* Drop into the debugger */ } -static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status) +static void status_handle(struct m68k_serial *info, unsigned short status) { #if 0 if(status & DCD) { @@ -289,7 +275,7 @@ static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short stat return; } -static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *regs, unsigned short rx) +static void receive_chars(struct m68k_serial *info, unsigned short rx) { struct tty_struct *tty = info->tty; m68328_uart *uart = &uart_addr[info->line]; @@ -328,14 +314,6 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg if(!tty) goto clear_and_exit; - /* - * Make sure that we do not overflow the buffer - */ - if (tty_request_buffer_room(tty, 1) == 0) { - tty_schedule_flip(tty); - return; - } - flag = TTY_NORMAL; if(rx & URX_PARITY_ERROR) { @@ -359,7 +337,7 @@ clear_and_exit: return; } -static _INLINE_ void transmit_chars(struct m68k_serial *info) +static void transmit_chars(struct m68k_serial *info) { m68328_uart *uart = &uart_addr[info->line]; @@ -398,7 +376,7 @@ clear_and_return: /* * This is the serial driver's generic interrupt routine */ -irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +irqreturn_t rs_interrupt(int irq, void *dev_id) { struct m68k_serial * info; m68328_uart *uart; @@ -415,10 +393,10 @@ irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) #ifdef USE_INTS tx = uart->utx.w; - if (rx & URX_DATA_READY) receive_chars(info, regs, rx); + if (rx & URX_DATA_READY) receive_chars(info, rx); if (tx & UTX_TX_AVAIL) transmit_chars(info); #else - receive_chars(info, regs, rx); + receive_chars(info, rx); #endif return IRQ_HANDLED; } @@ -474,7 +452,7 @@ static int startup(struct m68k_serial * info) return -ENOMEM; } - save_flags(flags); cli(); + local_irq_save(flags); /* * Clear the FIFO buffers and disable them @@ -507,7 +485,7 @@ static int startup(struct m68k_serial * info) change_speed(info); info->flags |= S_INITIALIZED; - restore_flags(flags); + local_irq_restore(flags); return 0; } @@ -524,7 +502,7 @@ static void shutdown(struct m68k_serial * info) if (!(info->flags & S_INITIALIZED)) return; - save_flags(flags); cli(); /* Disable interrupts */ + local_irq_save(flags); if (info->xmit_buf) { free_page((unsigned long) info->xmit_buf); @@ -535,7 +513,7 @@ static void shutdown(struct m68k_serial * info) set_bit(TTY_IO_ERROR, &info->tty->flags); info->flags &= ~S_INITIALIZED; - restore_flags(flags); + local_irq_restore(flags); } struct { @@ -656,24 +634,24 @@ static void rs_fair_output(void) if (info == 0) return; if (info->xmit_buf == 0) return; - save_flags(flags); cli(); + local_irq_save(flags); left = info->xmit_cnt; while (left != 0) { c = info->xmit_buf[info->xmit_tail]; info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; - restore_flags(flags); + local_irq_restore(flags); rs_put_char(c); - save_flags(flags); cli(); + local_irq_save(flags); left = min(info->xmit_cnt, left-1); } /* Last character is being transmitted now (hopefully). */ udelay(5); - restore_flags(flags); + local_irq_restore(flags); return; } @@ -721,11 +699,11 @@ static void rs_flush_chars(struct tty_struct *tty) #endif /* Enable transmitter */ - save_flags(flags); cli(); + local_irq_save(flags); if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) { - restore_flags(flags); + local_irq_restore(flags); return; } @@ -750,7 +728,7 @@ static void rs_flush_chars(struct tty_struct *tty) while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); } #endif - restore_flags(flags); + local_irq_restore(flags); } extern void console_printn(const char * b, int count); @@ -769,18 +747,22 @@ static int rs_write(struct tty_struct * tty, if (!tty || !info->xmit_buf) return 0; - save_flags(flags); + local_save_flags(flags); while (1) { - cli(); + local_irq_disable(); c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); + local_irq_restore(flags); + if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); + + local_irq_disable(); info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt += c; - restore_flags(flags); + local_irq_restore(flags); buf += c; count -= c; total += c; @@ -788,7 +770,7 @@ static int rs_write(struct tty_struct * tty, if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { /* Enable transmitter */ - cli(); + local_irq_disable(); #ifndef USE_INTS while(info->xmit_cnt) { #endif @@ -808,9 +790,9 @@ static int rs_write(struct tty_struct * tty, #ifndef USE_INTS } #endif - restore_flags(flags); + local_irq_restore(flags); } - restore_flags(flags); + return total; } @@ -839,12 +821,13 @@ static int rs_chars_in_buffer(struct tty_struct *tty) static void rs_flush_buffer(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; + unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) return; - cli(); + local_irq_save(flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); + local_irq_restore(flags); tty_wakeup(tty); } @@ -974,14 +957,15 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) m68328_uart *uart = &uart_addr[info->line]; #endif unsigned char status; + unsigned long flags; - cli(); + local_irq_save(flags); #ifdef CONFIG_SERIAL_68328_RTS_CTS status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; #else status = 0; #endif - sti(); + local_irq_restore(flags); put_user(status,value); return 0; } @@ -995,14 +979,13 @@ static void send_break(struct m68k_serial * info, unsigned int duration) unsigned long flags; if (!info->port) return; - save_flags(flags); - cli(); + local_irq_save(flags); #ifdef USE_INTS uart->utx.w |= UTX_SEND_BREAK; msleep_interruptible(duration); uart->utx.w &= ~UTX_SEND_BREAK; #endif - restore_flags(flags); + local_irq_restore(flags); } static int rs_ioctl(struct tty_struct *tty, struct file * file, @@ -1061,7 +1044,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, (struct serial_struct *) arg); case TIOCSERGETLSR: /* Get line status register */ if (access_ok(VERIFY_WRITE, (void *) arg, - sizeof(unsigned int)); + sizeof(unsigned int))) return get_lsr_info(info, (unsigned int *) arg); return -EFAULT; case TIOCSERGSTRUCT: @@ -1078,7 +1061,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, return 0; } -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; @@ -1114,10 +1097,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) if (!info || serial_paranoia_check(info, tty->name, "rs_close")) return; - save_flags(flags); cli(); + local_irq_save(flags); if (tty_hung_up_p(filp)) { - restore_flags(flags); + local_irq_restore(flags); return; } @@ -1139,7 +1122,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) info->count = 0; } if (info->count) { - restore_flags(flags); + local_irq_restore(flags); return; } info->flags |= S_CLOSING; @@ -1187,7 +1170,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); wake_up_interruptible(&info->close_wait); - restore_flags(flags); + local_irq_restore(flags); } /* @@ -1263,9 +1246,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, info->count--; info->blocked_open++; while (1) { - cli(); + local_irq_disable(); m68k_rtsdtr(info, 1); - sti(); + local_irq_enable(); current->state = TASK_INTERRUPTIBLE; if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) { @@ -1394,7 +1377,7 @@ void startup_console(void) #endif /* CONFIG_PM_LEGACY */ -static struct tty_operations rs_ops = { +static const struct tty_operations rs_ops = { .open = rs_open, .close = rs_close, .write = rs_write, @@ -1445,7 +1428,7 @@ rs68328_init(void) return -ENOMEM; } - save_flags(flags); cli(); + local_irq_save(flags); for(i=0;idata = info; #endif } - restore_flags(flags); + local_irq_restore(flags); return 0; }