|
@@ -131,17 +131,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)
|
|
|
{
|
|
@@ -211,16 +200,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++;
|
|
@@ -229,7 +218,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)
|
|
@@ -241,7 +230,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;
|
|
@@ -249,7 +238,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
|
|
@@ -327,14 +316,6 @@ static void receive_chars(struct m68k_serial *info, struct pt_regs *regs,
|
|
|
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) {
|
|
@@ -473,7 +454,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
|
|
@@ -506,7 +487,7 @@ static int startup(struct m68k_serial * info)
|
|
|
change_speed(info);
|
|
|
|
|
|
info->flags |= S_INITIALIZED;
|
|
|
- restore_flags(flags);
|
|
|
+ local_irq_restore(flags);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -523,7 +504,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);
|
|
@@ -534,7 +515,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 {
|
|
@@ -655,24 +636,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;
|
|
|
}
|
|
|
|
|
@@ -720,11 +701,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;
|
|
|
}
|
|
|
|
|
@@ -749,7 +730,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);
|
|
@@ -768,18 +749,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;
|
|
@@ -787,7 +772,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
|
|
@@ -807,9 +792,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;
|
|
|
}
|
|
|
|
|
@@ -838,12 +823,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);
|
|
|
}
|
|
|
|
|
@@ -973,14 +959,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;
|
|
|
}
|
|
@@ -994,14 +981,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,
|
|
@@ -1060,7 +1046,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:
|
|
@@ -1113,10 +1099,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;
|
|
|
}
|
|
|
|
|
@@ -1138,7 +1124,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;
|
|
@@ -1186,7 +1172,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);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1262,9 +1248,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)) {
|
|
@@ -1444,7 +1430,7 @@ rs68328_init(void)
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- save_flags(flags); cli();
|
|
|
+ local_irq_save(flags);
|
|
|
|
|
|
for(i=0;i<NR_PORTS;i++) {
|
|
|
|
|
@@ -1489,7 +1475,7 @@ rs68328_init(void)
|
|
|
serial_pm[i]->data = info;
|
|
|
#endif
|
|
|
}
|
|
|
- restore_flags(flags);
|
|
|
+ local_irq_restore(flags);
|
|
|
return 0;
|
|
|
}
|
|
|
|