aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/68328serial.c102
1 files changed, 44 insertions, 58 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index b88a7c1158af..bff94541991c 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -131,17 +131,6 @@ static int m68328_console_baud = CONSOLE_BAUD_RATE;
131static int m68328_console_cbaud = DEFAULT_CBAUD; 131static int m68328_console_cbaud = DEFAULT_CBAUD;
132 132
133 133
134/*
135 * tmp_buf is used as a temporary buffer by serial_write. We need to
136 * lock it in case the memcpy_fromfs blocks while swapping in a page,
137 * and some other program tries to do a serial write at the same time.
138 * Since the lock will only come under contention when the system is
139 * swapping and available memory is low, it makes sense to share one
140 * buffer across all the serial ports, since it significantly saves
141 * memory if large numbers of serial ports are open.
142 */
143static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
144
145static inline int serial_paranoia_check(struct m68k_serial *info, 134static inline int serial_paranoia_check(struct m68k_serial *info,
146 char *name, const char *routine) 135 char *name, const char *routine)
147{ 136{
@@ -211,16 +200,16 @@ static void rs_stop(struct tty_struct *tty)
211 if (serial_paranoia_check(info, tty->name, "rs_stop")) 200 if (serial_paranoia_check(info, tty->name, "rs_stop"))
212 return; 201 return;
213 202
214 save_flags(flags); cli(); 203 local_irq_save(flags);
215 uart->ustcnt &= ~USTCNT_TXEN; 204 uart->ustcnt &= ~USTCNT_TXEN;
216 restore_flags(flags); 205 local_irq_restore(flags);
217} 206}
218 207
219static void rs_put_char(char ch) 208static void rs_put_char(char ch)
220{ 209{
221 int flags, loops = 0; 210 int flags, loops = 0;
222 211
223 save_flags(flags); cli(); 212 local_irq_save(flags);
224 213
225 while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { 214 while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) {
226 loops++; 215 loops++;
@@ -229,7 +218,7 @@ static void rs_put_char(char ch)
229 218
230 UTX_TXDATA = ch; 219 UTX_TXDATA = ch;
231 udelay(5); 220 udelay(5);
232 restore_flags(flags); 221 local_irq_restore(flags);
233} 222}
234 223
235static void rs_start(struct tty_struct *tty) 224static void rs_start(struct tty_struct *tty)
@@ -241,7 +230,7 @@ static void rs_start(struct tty_struct *tty)
241 if (serial_paranoia_check(info, tty->name, "rs_start")) 230 if (serial_paranoia_check(info, tty->name, "rs_start"))
242 return; 231 return;
243 232
244 save_flags(flags); cli(); 233 local_irq_save(flags);
245 if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { 234 if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) {
246#ifdef USE_INTS 235#ifdef USE_INTS
247 uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; 236 uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK;
@@ -249,7 +238,7 @@ static void rs_start(struct tty_struct *tty)
249 uart->ustcnt |= USTCNT_TXEN; 238 uart->ustcnt |= USTCNT_TXEN;
250#endif 239#endif
251 } 240 }
252 restore_flags(flags); 241 local_irq_restore(flags);
253} 242}
254 243
255/* Drop into either the boot monitor or kadb upon receiving a break 244/* 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,
327 if(!tty) 316 if(!tty)
328 goto clear_and_exit; 317 goto clear_and_exit;
329 318
330 /*
331 * Make sure that we do not overflow the buffer
332 */
333 if (tty_request_buffer_room(tty, 1) == 0) {
334 tty_schedule_flip(tty);
335 return;
336 }
337
338 flag = TTY_NORMAL; 319 flag = TTY_NORMAL;
339 320
340 if(rx & URX_PARITY_ERROR) { 321 if(rx & URX_PARITY_ERROR) {
@@ -473,7 +454,7 @@ static int startup(struct m68k_serial * info)
473 return -ENOMEM; 454 return -ENOMEM;
474 } 455 }
475 456
476 save_flags(flags); cli(); 457 local_irq_save(flags);
477 458
478 /* 459 /*
479 * Clear the FIFO buffers and disable them 460 * Clear the FIFO buffers and disable them
@@ -506,7 +487,7 @@ static int startup(struct m68k_serial * info)
506 change_speed(info); 487 change_speed(info);
507 488
508 info->flags |= S_INITIALIZED; 489 info->flags |= S_INITIALIZED;
509 restore_flags(flags); 490 local_irq_restore(flags);
510 return 0; 491 return 0;
511} 492}
512 493
@@ -523,7 +504,7 @@ static void shutdown(struct m68k_serial * info)
523 if (!(info->flags & S_INITIALIZED)) 504 if (!(info->flags & S_INITIALIZED))
524 return; 505 return;
525 506
526 save_flags(flags); cli(); /* Disable interrupts */ 507 local_irq_save(flags);
527 508
528 if (info->xmit_buf) { 509 if (info->xmit_buf) {
529 free_page((unsigned long) info->xmit_buf); 510 free_page((unsigned long) info->xmit_buf);
@@ -534,7 +515,7 @@ static void shutdown(struct m68k_serial * info)
534 set_bit(TTY_IO_ERROR, &info->tty->flags); 515 set_bit(TTY_IO_ERROR, &info->tty->flags);
535 516
536 info->flags &= ~S_INITIALIZED; 517 info->flags &= ~S_INITIALIZED;
537 restore_flags(flags); 518 local_irq_restore(flags);
538} 519}
539 520
540struct { 521struct {
@@ -655,24 +636,24 @@ static void rs_fair_output(void)
655 if (info == 0) return; 636 if (info == 0) return;
656 if (info->xmit_buf == 0) return; 637 if (info->xmit_buf == 0) return;
657 638
658 save_flags(flags); cli(); 639 local_irq_save(flags);
659 left = info->xmit_cnt; 640 left = info->xmit_cnt;
660 while (left != 0) { 641 while (left != 0) {
661 c = info->xmit_buf[info->xmit_tail]; 642 c = info->xmit_buf[info->xmit_tail];
662 info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); 643 info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1);
663 info->xmit_cnt--; 644 info->xmit_cnt--;
664 restore_flags(flags); 645 local_irq_restore(flags);
665 646
666 rs_put_char(c); 647 rs_put_char(c);
667 648
668 save_flags(flags); cli(); 649 local_irq_save(flags);
669 left = min(info->xmit_cnt, left-1); 650 left = min(info->xmit_cnt, left-1);
670 } 651 }
671 652
672 /* Last character is being transmitted now (hopefully). */ 653 /* Last character is being transmitted now (hopefully). */
673 udelay(5); 654 udelay(5);
674 655
675 restore_flags(flags); 656 local_irq_restore(flags);
676 return; 657 return;
677} 658}
678 659
@@ -720,11 +701,11 @@ static void rs_flush_chars(struct tty_struct *tty)
720#endif 701#endif
721 702
722 /* Enable transmitter */ 703 /* Enable transmitter */
723 save_flags(flags); cli(); 704 local_irq_save(flags);
724 705
725 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 706 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
726 !info->xmit_buf) { 707 !info->xmit_buf) {
727 restore_flags(flags); 708 local_irq_restore(flags);
728 return; 709 return;
729 } 710 }
730 711
@@ -749,7 +730,7 @@ static void rs_flush_chars(struct tty_struct *tty)
749 while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); 730 while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5);
750 } 731 }
751#endif 732#endif
752 restore_flags(flags); 733 local_irq_restore(flags);
753} 734}
754 735
755extern void console_printn(const char * b, int count); 736extern void console_printn(const char * b, int count);
@@ -768,18 +749,22 @@ static int rs_write(struct tty_struct * tty,
768 if (!tty || !info->xmit_buf) 749 if (!tty || !info->xmit_buf)
769 return 0; 750 return 0;
770 751
771 save_flags(flags); 752 local_save_flags(flags);
772 while (1) { 753 while (1) {
773 cli(); 754 local_irq_disable();
774 c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, 755 c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
775 SERIAL_XMIT_SIZE - info->xmit_head)); 756 SERIAL_XMIT_SIZE - info->xmit_head));
757 local_irq_restore(flags);
758
776 if (c <= 0) 759 if (c <= 0)
777 break; 760 break;
778 761
779 memcpy(info->xmit_buf + info->xmit_head, buf, c); 762 memcpy(info->xmit_buf + info->xmit_head, buf, c);
763
764 local_irq_disable();
780 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); 765 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
781 info->xmit_cnt += c; 766 info->xmit_cnt += c;
782 restore_flags(flags); 767 local_irq_restore(flags);
783 buf += c; 768 buf += c;
784 count -= c; 769 count -= c;
785 total += c; 770 total += c;
@@ -787,7 +772,7 @@ static int rs_write(struct tty_struct * tty,
787 772
788 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { 773 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
789 /* Enable transmitter */ 774 /* Enable transmitter */
790 cli(); 775 local_irq_disable();
791#ifndef USE_INTS 776#ifndef USE_INTS
792 while(info->xmit_cnt) { 777 while(info->xmit_cnt) {
793#endif 778#endif
@@ -807,9 +792,9 @@ static int rs_write(struct tty_struct * tty,
807#ifndef USE_INTS 792#ifndef USE_INTS
808 } 793 }
809#endif 794#endif
810 restore_flags(flags); 795 local_irq_restore(flags);
811 } 796 }
812 restore_flags(flags); 797
813 return total; 798 return total;
814} 799}
815 800
@@ -838,12 +823,13 @@ static int rs_chars_in_buffer(struct tty_struct *tty)
838static void rs_flush_buffer(struct tty_struct *tty) 823static void rs_flush_buffer(struct tty_struct *tty)
839{ 824{
840 struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; 825 struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
826 unsigned long flags;
841 827
842 if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) 828 if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
843 return; 829 return;
844 cli(); 830 local_irq_save(flags);
845 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 831 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
846 sti(); 832 local_irq_restore(flags);
847 tty_wakeup(tty); 833 tty_wakeup(tty);
848} 834}
849 835
@@ -973,14 +959,15 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
973 m68328_uart *uart = &uart_addr[info->line]; 959 m68328_uart *uart = &uart_addr[info->line];
974#endif 960#endif
975 unsigned char status; 961 unsigned char status;
962 unsigned long flags;
976 963
977 cli(); 964 local_irq_save(flags);
978#ifdef CONFIG_SERIAL_68328_RTS_CTS 965#ifdef CONFIG_SERIAL_68328_RTS_CTS
979 status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; 966 status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0;
980#else 967#else
981 status = 0; 968 status = 0;
982#endif 969#endif
983 sti(); 970 local_irq_restore(flags);
984 put_user(status,value); 971 put_user(status,value);
985 return 0; 972 return 0;
986} 973}
@@ -994,14 +981,13 @@ static void send_break(struct m68k_serial * info, unsigned int duration)
994 unsigned long flags; 981 unsigned long flags;
995 if (!info->port) 982 if (!info->port)
996 return; 983 return;
997 save_flags(flags); 984 local_irq_save(flags);
998 cli();
999#ifdef USE_INTS 985#ifdef USE_INTS
1000 uart->utx.w |= UTX_SEND_BREAK; 986 uart->utx.w |= UTX_SEND_BREAK;
1001 msleep_interruptible(duration); 987 msleep_interruptible(duration);
1002 uart->utx.w &= ~UTX_SEND_BREAK; 988 uart->utx.w &= ~UTX_SEND_BREAK;
1003#endif 989#endif
1004 restore_flags(flags); 990 local_irq_restore(flags);
1005} 991}
1006 992
1007static int rs_ioctl(struct tty_struct *tty, struct file * file, 993static 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,
1060 (struct serial_struct *) arg); 1046 (struct serial_struct *) arg);
1061 case TIOCSERGETLSR: /* Get line status register */ 1047 case TIOCSERGETLSR: /* Get line status register */
1062 if (access_ok(VERIFY_WRITE, (void *) arg, 1048 if (access_ok(VERIFY_WRITE, (void *) arg,
1063 sizeof(unsigned int)); 1049 sizeof(unsigned int)))
1064 return get_lsr_info(info, (unsigned int *) arg); 1050 return get_lsr_info(info, (unsigned int *) arg);
1065 return -EFAULT; 1051 return -EFAULT;
1066 case TIOCSERGSTRUCT: 1052 case TIOCSERGSTRUCT:
@@ -1113,10 +1099,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
1113 if (!info || serial_paranoia_check(info, tty->name, "rs_close")) 1099 if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
1114 return; 1100 return;
1115 1101
1116 save_flags(flags); cli(); 1102 local_irq_save(flags);
1117 1103
1118 if (tty_hung_up_p(filp)) { 1104 if (tty_hung_up_p(filp)) {
1119 restore_flags(flags); 1105 local_irq_restore(flags);
1120 return; 1106 return;
1121 } 1107 }
1122 1108
@@ -1138,7 +1124,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
1138 info->count = 0; 1124 info->count = 0;
1139 } 1125 }
1140 if (info->count) { 1126 if (info->count) {
1141 restore_flags(flags); 1127 local_irq_restore(flags);
1142 return; 1128 return;
1143 } 1129 }
1144 info->flags |= S_CLOSING; 1130 info->flags |= S_CLOSING;
@@ -1186,7 +1172,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
1186 } 1172 }
1187 info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); 1173 info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING);
1188 wake_up_interruptible(&info->close_wait); 1174 wake_up_interruptible(&info->close_wait);
1189 restore_flags(flags); 1175 local_irq_restore(flags);
1190} 1176}
1191 1177
1192/* 1178/*
@@ -1262,9 +1248,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1262 info->count--; 1248 info->count--;
1263 info->blocked_open++; 1249 info->blocked_open++;
1264 while (1) { 1250 while (1) {
1265 cli(); 1251 local_irq_disable();
1266 m68k_rtsdtr(info, 1); 1252 m68k_rtsdtr(info, 1);
1267 sti(); 1253 local_irq_enable();
1268 current->state = TASK_INTERRUPTIBLE; 1254 current->state = TASK_INTERRUPTIBLE;
1269 if (tty_hung_up_p(filp) || 1255 if (tty_hung_up_p(filp) ||
1270 !(info->flags & S_INITIALIZED)) { 1256 !(info->flags & S_INITIALIZED)) {
@@ -1444,7 +1430,7 @@ rs68328_init(void)
1444 return -ENOMEM; 1430 return -ENOMEM;
1445 } 1431 }
1446 1432
1447 save_flags(flags); cli(); 1433 local_irq_save(flags);
1448 1434
1449 for(i=0;i<NR_PORTS;i++) { 1435 for(i=0;i<NR_PORTS;i++) {
1450 1436
@@ -1489,7 +1475,7 @@ rs68328_init(void)
1489 serial_pm[i]->data = info; 1475 serial_pm[i]->data = info;
1490#endif 1476#endif
1491 } 1477 }
1492 restore_flags(flags); 1478 local_irq_restore(flags);
1493 return 0; 1479 return 0;
1494} 1480}
1495 1481