diff options
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 211 |
1 files changed, 89 insertions, 122 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 38fdd4da2427..0f7a542d9041 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -140,15 +140,6 @@ static char *stl_drvversion = "5.6.0"; | |||
140 | static struct tty_driver *stl_serial; | 140 | static struct tty_driver *stl_serial; |
141 | 141 | ||
142 | /* | 142 | /* |
143 | * We will need to allocate a temporary write buffer for chars that | ||
144 | * come direct from user space. The problem is that a copy from user | ||
145 | * space might cause a page fault (typically on a system that is | ||
146 | * swapping!). All ports will share one buffer - since if the system | ||
147 | * is already swapping a shared buffer won't make things any worse. | ||
148 | */ | ||
149 | static char *stl_tmpwritebuf; | ||
150 | |||
151 | /* | ||
152 | * Define a local default termios struct. All ports will be created | 143 | * Define a local default termios struct. All ports will be created |
153 | * with this termios initially. Basically all it defines is a raw port | 144 | * with this termios initially. Basically all it defines is a raw port |
154 | * at 9600, 8 data bits, 1 stop bit. | 145 | * at 9600, 8 data bits, 1 stop bit. |
@@ -362,6 +353,14 @@ static unsigned char stl_vecmap[] = { | |||
362 | }; | 353 | }; |
363 | 354 | ||
364 | /* | 355 | /* |
356 | * Lock ordering is that you may not take stallion_lock holding | ||
357 | * brd_lock. | ||
358 | */ | ||
359 | |||
360 | static spinlock_t brd_lock; /* Guard the board mapping */ | ||
361 | static spinlock_t stallion_lock; /* Guard the tty driver */ | ||
362 | |||
363 | /* | ||
365 | * Set up enable and disable macros for the ECH boards. They require | 364 | * Set up enable and disable macros for the ECH boards. They require |
366 | * the secondary io address space to be activated and deactivated. | 365 | * the secondary io address space to be activated and deactivated. |
367 | * This way all ECH boards can share their secondary io region. | 366 | * This way all ECH boards can share their secondary io region. |
@@ -724,17 +723,7 @@ static struct class *stallion_class; | |||
724 | 723 | ||
725 | static int __init stallion_module_init(void) | 724 | static int __init stallion_module_init(void) |
726 | { | 725 | { |
727 | unsigned long flags; | ||
728 | |||
729 | #ifdef DEBUG | ||
730 | printk("init_module()\n"); | ||
731 | #endif | ||
732 | |||
733 | save_flags(flags); | ||
734 | cli(); | ||
735 | stl_init(); | 726 | stl_init(); |
736 | restore_flags(flags); | ||
737 | |||
738 | return 0; | 727 | return 0; |
739 | } | 728 | } |
740 | 729 | ||
@@ -745,7 +734,6 @@ static void __exit stallion_module_exit(void) | |||
745 | stlbrd_t *brdp; | 734 | stlbrd_t *brdp; |
746 | stlpanel_t *panelp; | 735 | stlpanel_t *panelp; |
747 | stlport_t *portp; | 736 | stlport_t *portp; |
748 | unsigned long flags; | ||
749 | int i, j, k; | 737 | int i, j, k; |
750 | 738 | ||
751 | #ifdef DEBUG | 739 | #ifdef DEBUG |
@@ -755,9 +743,6 @@ static void __exit stallion_module_exit(void) | |||
755 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | 743 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, |
756 | stl_drvversion); | 744 | stl_drvversion); |
757 | 745 | ||
758 | save_flags(flags); | ||
759 | cli(); | ||
760 | |||
761 | /* | 746 | /* |
762 | * Free up all allocated resources used by the ports. This includes | 747 | * Free up all allocated resources used by the ports. This includes |
763 | * memory and interrupts. As part of this process we will also do | 748 | * memory and interrupts. As part of this process we will also do |
@@ -769,7 +754,6 @@ static void __exit stallion_module_exit(void) | |||
769 | if (i) { | 754 | if (i) { |
770 | printk("STALLION: failed to un-register tty driver, " | 755 | printk("STALLION: failed to un-register tty driver, " |
771 | "errno=%d\n", -i); | 756 | "errno=%d\n", -i); |
772 | restore_flags(flags); | ||
773 | return; | 757 | return; |
774 | } | 758 | } |
775 | for (i = 0; i < 4; i++) | 759 | for (i = 0; i < 4; i++) |
@@ -779,8 +763,6 @@ static void __exit stallion_module_exit(void) | |||
779 | "errno=%d\n", -i); | 763 | "errno=%d\n", -i); |
780 | class_destroy(stallion_class); | 764 | class_destroy(stallion_class); |
781 | 765 | ||
782 | kfree(stl_tmpwritebuf); | ||
783 | |||
784 | for (i = 0; (i < stl_nrbrds); i++) { | 766 | for (i = 0; (i < stl_nrbrds); i++) { |
785 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | 767 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) |
786 | continue; | 768 | continue; |
@@ -810,8 +792,6 @@ static void __exit stallion_module_exit(void) | |||
810 | kfree(brdp); | 792 | kfree(brdp); |
811 | stl_brds[i] = (stlbrd_t *) NULL; | 793 | stl_brds[i] = (stlbrd_t *) NULL; |
812 | } | 794 | } |
813 | |||
814 | restore_flags(flags); | ||
815 | } | 795 | } |
816 | 796 | ||
817 | module_init(stallion_module_init); | 797 | module_init(stallion_module_init); |
@@ -944,7 +924,7 @@ static stlbrd_t *stl_allocbrd(void) | |||
944 | 924 | ||
945 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 925 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
946 | if (!brdp) { | 926 | if (!brdp) { |
947 | printk("STALLION: failed to allocate memory (size=%d)\n", | 927 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
948 | sizeof(stlbrd_t)); | 928 | sizeof(stlbrd_t)); |
949 | return NULL; | 929 | return NULL; |
950 | } | 930 | } |
@@ -1062,16 +1042,17 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1062 | rc = 0; | 1042 | rc = 0; |
1063 | doclocal = 0; | 1043 | doclocal = 0; |
1064 | 1044 | ||
1045 | spin_lock_irqsave(&stallion_lock, flags); | ||
1046 | |||
1065 | if (portp->tty->termios->c_cflag & CLOCAL) | 1047 | if (portp->tty->termios->c_cflag & CLOCAL) |
1066 | doclocal++; | 1048 | doclocal++; |
1067 | 1049 | ||
1068 | save_flags(flags); | ||
1069 | cli(); | ||
1070 | portp->openwaitcnt++; | 1050 | portp->openwaitcnt++; |
1071 | if (! tty_hung_up_p(filp)) | 1051 | if (! tty_hung_up_p(filp)) |
1072 | portp->refcount--; | 1052 | portp->refcount--; |
1073 | 1053 | ||
1074 | for (;;) { | 1054 | for (;;) { |
1055 | /* Takes brd_lock internally */ | ||
1075 | stl_setsignals(portp, 1, 1); | 1056 | stl_setsignals(portp, 1, 1); |
1076 | if (tty_hung_up_p(filp) || | 1057 | if (tty_hung_up_p(filp) || |
1077 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { | 1058 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { |
@@ -1089,13 +1070,14 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1089 | rc = -ERESTARTSYS; | 1070 | rc = -ERESTARTSYS; |
1090 | break; | 1071 | break; |
1091 | } | 1072 | } |
1073 | /* FIXME */ | ||
1092 | interruptible_sleep_on(&portp->open_wait); | 1074 | interruptible_sleep_on(&portp->open_wait); |
1093 | } | 1075 | } |
1094 | 1076 | ||
1095 | if (! tty_hung_up_p(filp)) | 1077 | if (! tty_hung_up_p(filp)) |
1096 | portp->refcount++; | 1078 | portp->refcount++; |
1097 | portp->openwaitcnt--; | 1079 | portp->openwaitcnt--; |
1098 | restore_flags(flags); | 1080 | spin_unlock_irqrestore(&stallion_lock, flags); |
1099 | 1081 | ||
1100 | return rc; | 1082 | return rc; |
1101 | } | 1083 | } |
@@ -1115,16 +1097,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1115 | if (portp == (stlport_t *) NULL) | 1097 | if (portp == (stlport_t *) NULL) |
1116 | return; | 1098 | return; |
1117 | 1099 | ||
1118 | save_flags(flags); | 1100 | spin_lock_irqsave(&stallion_lock, flags); |
1119 | cli(); | ||
1120 | if (tty_hung_up_p(filp)) { | 1101 | if (tty_hung_up_p(filp)) { |
1121 | restore_flags(flags); | 1102 | spin_unlock_irqrestore(&stallion_lock, flags); |
1122 | return; | 1103 | return; |
1123 | } | 1104 | } |
1124 | if ((tty->count == 1) && (portp->refcount != 1)) | 1105 | if ((tty->count == 1) && (portp->refcount != 1)) |
1125 | portp->refcount = 1; | 1106 | portp->refcount = 1; |
1126 | if (portp->refcount-- > 1) { | 1107 | if (portp->refcount-- > 1) { |
1127 | restore_flags(flags); | 1108 | spin_unlock_irqrestore(&stallion_lock, flags); |
1128 | return; | 1109 | return; |
1129 | } | 1110 | } |
1130 | 1111 | ||
@@ -1138,11 +1119,18 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1138 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | 1119 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) |
1139 | */ | 1120 | */ |
1140 | tty->closing = 1; | 1121 | tty->closing = 1; |
1122 | |||
1123 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1124 | |||
1141 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1125 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1142 | tty_wait_until_sent(tty, portp->closing_wait); | 1126 | tty_wait_until_sent(tty, portp->closing_wait); |
1143 | stl_waituntilsent(tty, (HZ / 2)); | 1127 | stl_waituntilsent(tty, (HZ / 2)); |
1144 | 1128 | ||
1129 | |||
1130 | spin_lock_irqsave(&stallion_lock, flags); | ||
1145 | portp->flags &= ~ASYNC_INITIALIZED; | 1131 | portp->flags &= ~ASYNC_INITIALIZED; |
1132 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1133 | |||
1146 | stl_disableintrs(portp); | 1134 | stl_disableintrs(portp); |
1147 | if (tty->termios->c_cflag & HUPCL) | 1135 | if (tty->termios->c_cflag & HUPCL) |
1148 | stl_setsignals(portp, 0, 0); | 1136 | stl_setsignals(portp, 0, 0); |
@@ -1169,7 +1157,6 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1169 | 1157 | ||
1170 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1158 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1171 | wake_up_interruptible(&portp->close_wait); | 1159 | wake_up_interruptible(&portp->close_wait); |
1172 | restore_flags(flags); | ||
1173 | } | 1160 | } |
1174 | 1161 | ||
1175 | /*****************************************************************************/ | 1162 | /*****************************************************************************/ |
@@ -1191,9 +1178,6 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1191 | (int) tty, (int) buf, count); | 1178 | (int) tty, (int) buf, count); |
1192 | #endif | 1179 | #endif |
1193 | 1180 | ||
1194 | if ((tty == (struct tty_struct *) NULL) || | ||
1195 | (stl_tmpwritebuf == (char *) NULL)) | ||
1196 | return 0; | ||
1197 | portp = tty->driver_data; | 1181 | portp = tty->driver_data; |
1198 | if (portp == (stlport_t *) NULL) | 1182 | if (portp == (stlport_t *) NULL) |
1199 | return 0; | 1183 | return 0; |
@@ -1298,11 +1282,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1298 | if (portp->tx.buf == (char *) NULL) | 1282 | if (portp->tx.buf == (char *) NULL) |
1299 | return; | 1283 | return; |
1300 | 1284 | ||
1301 | #if 0 | ||
1302 | if (tty->stopped || tty->hw_stopped || | ||
1303 | (portp->tx.head == portp->tx.tail)) | ||
1304 | return; | ||
1305 | #endif | ||
1306 | stl_startrxtx(portp, -1, 1); | 1285 | stl_startrxtx(portp, -1, 1); |
1307 | } | 1286 | } |
1308 | 1287 | ||
@@ -1973,12 +1952,14 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
1973 | unsigned int iobase; | 1952 | unsigned int iobase; |
1974 | int handled = 0; | 1953 | int handled = 0; |
1975 | 1954 | ||
1955 | spin_lock(&brd_lock); | ||
1976 | panelp = brdp->panels[0]; | 1956 | panelp = brdp->panels[0]; |
1977 | iobase = panelp->iobase; | 1957 | iobase = panelp->iobase; |
1978 | while (inb(brdp->iostatus) & EIO_INTRPEND) { | 1958 | while (inb(brdp->iostatus) & EIO_INTRPEND) { |
1979 | handled = 1; | 1959 | handled = 1; |
1980 | (* panelp->isr)(panelp, iobase); | 1960 | (* panelp->isr)(panelp, iobase); |
1981 | } | 1961 | } |
1962 | spin_unlock(&brd_lock); | ||
1982 | return handled; | 1963 | return handled; |
1983 | } | 1964 | } |
1984 | 1965 | ||
@@ -2164,7 +2145,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2164 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 2145 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
2165 | if (!portp) { | 2146 | if (!portp) { |
2166 | printk("STALLION: failed to allocate memory " | 2147 | printk("STALLION: failed to allocate memory " |
2167 | "(size=%d)\n", sizeof(stlport_t)); | 2148 | "(size=%Zd)\n", sizeof(stlport_t)); |
2168 | break; | 2149 | break; |
2169 | } | 2150 | } |
2170 | 2151 | ||
@@ -2300,7 +2281,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2300 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2281 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2301 | if (!panelp) { | 2282 | if (!panelp) { |
2302 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2283 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2303 | "(size=%d)\n", sizeof(stlpanel_t)); | 2284 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2304 | return -ENOMEM; | 2285 | return -ENOMEM; |
2305 | } | 2286 | } |
2306 | 2287 | ||
@@ -2474,7 +2455,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2474 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2455 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2475 | if (!panelp) { | 2456 | if (!panelp) { |
2476 | printk("STALLION: failed to allocate memory " | 2457 | printk("STALLION: failed to allocate memory " |
2477 | "(size=%d)\n", sizeof(stlpanel_t)); | 2458 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2478 | break; | 2459 | break; |
2479 | } | 2460 | } |
2480 | panelp->magic = STL_PANELMAGIC; | 2461 | panelp->magic = STL_PANELMAGIC; |
@@ -2875,8 +2856,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2875 | portp->stats.lflags = 0; | 2856 | portp->stats.lflags = 0; |
2876 | portp->stats.rxbuffered = 0; | 2857 | portp->stats.rxbuffered = 0; |
2877 | 2858 | ||
2878 | save_flags(flags); | 2859 | spin_lock_irqsave(&stallion_lock, flags); |
2879 | cli(); | ||
2880 | if (portp->tty != (struct tty_struct *) NULL) { | 2860 | if (portp->tty != (struct tty_struct *) NULL) { |
2881 | if (portp->tty->driver_data == portp) { | 2861 | if (portp->tty->driver_data == portp) { |
2882 | portp->stats.ttystate = portp->tty->flags; | 2862 | portp->stats.ttystate = portp->tty->flags; |
@@ -2890,7 +2870,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2890 | } | 2870 | } |
2891 | } | 2871 | } |
2892 | } | 2872 | } |
2893 | restore_flags(flags); | 2873 | spin_unlock_irqrestore(&stallion_lock, flags); |
2894 | 2874 | ||
2895 | head = portp->tx.head; | 2875 | head = portp->tx.head; |
2896 | tail = portp->tx.tail; | 2876 | tail = portp->tx.tail; |
@@ -3045,6 +3025,9 @@ static int __init stl_init(void) | |||
3045 | int i; | 3025 | int i; |
3046 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | 3026 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); |
3047 | 3027 | ||
3028 | spin_lock_init(&stallion_lock); | ||
3029 | spin_lock_init(&brd_lock); | ||
3030 | |||
3048 | stl_initbrds(); | 3031 | stl_initbrds(); |
3049 | 3032 | ||
3050 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | 3033 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); |
@@ -3052,14 +3035,6 @@ static int __init stl_init(void) | |||
3052 | return -1; | 3035 | return -1; |
3053 | 3036 | ||
3054 | /* | 3037 | /* |
3055 | * Allocate a temporary write buffer. | ||
3056 | */ | ||
3057 | stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
3058 | if (!stl_tmpwritebuf) | ||
3059 | printk("STALLION: failed to allocate memory (size=%d)\n", | ||
3060 | STL_TXBUFSIZE); | ||
3061 | |||
3062 | /* | ||
3063 | * Set up a character driver for per board stuff. This is mainly used | 3038 | * Set up a character driver for per board stuff. This is mainly used |
3064 | * to do stats ioctls on the ports. | 3039 | * to do stats ioctls on the ports. |
3065 | */ | 3040 | */ |
@@ -3137,11 +3112,13 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3137 | unsigned int gfrcr; | 3112 | unsigned int gfrcr; |
3138 | int chipmask, i, j; | 3113 | int chipmask, i, j; |
3139 | int nrchips, uartaddr, ioaddr; | 3114 | int nrchips, uartaddr, ioaddr; |
3115 | unsigned long flags; | ||
3140 | 3116 | ||
3141 | #ifdef DEBUG | 3117 | #ifdef DEBUG |
3142 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | 3118 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); |
3143 | #endif | 3119 | #endif |
3144 | 3120 | ||
3121 | spin_lock_irqsave(&brd_lock, flags); | ||
3145 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3122 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
3146 | 3123 | ||
3147 | /* | 3124 | /* |
@@ -3179,6 +3156,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3179 | } | 3156 | } |
3180 | 3157 | ||
3181 | BRDDISABLE(panelp->brdnr); | 3158 | BRDDISABLE(panelp->brdnr); |
3159 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3182 | return chipmask; | 3160 | return chipmask; |
3183 | } | 3161 | } |
3184 | 3162 | ||
@@ -3190,6 +3168,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3190 | 3168 | ||
3191 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 3169 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) |
3192 | { | 3170 | { |
3171 | unsigned long flags; | ||
3193 | #ifdef DEBUG | 3172 | #ifdef DEBUG |
3194 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3173 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", |
3195 | (int) brdp, (int) panelp, (int) portp); | 3174 | (int) brdp, (int) panelp, (int) portp); |
@@ -3199,6 +3178,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3199 | (portp == (stlport_t *) NULL)) | 3178 | (portp == (stlport_t *) NULL)) |
3200 | return; | 3179 | return; |
3201 | 3180 | ||
3181 | spin_lock_irqsave(&brd_lock, flags); | ||
3202 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || | 3182 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || |
3203 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); | 3183 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); |
3204 | portp->uartaddr = (portp->portnr & 0x04) << 5; | 3184 | portp->uartaddr = (portp->portnr & 0x04) << 5; |
@@ -3209,6 +3189,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3209 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); | 3189 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); |
3210 | portp->hwid = stl_cd1400getreg(portp, GFRCR); | 3190 | portp->hwid = stl_cd1400getreg(portp, GFRCR); |
3211 | BRDDISABLE(portp->brdnr); | 3191 | BRDDISABLE(portp->brdnr); |
3192 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3212 | } | 3193 | } |
3213 | 3194 | ||
3214 | /*****************************************************************************/ | 3195 | /*****************************************************************************/ |
@@ -3418,8 +3399,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3418 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3399 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
3419 | #endif | 3400 | #endif |
3420 | 3401 | ||
3421 | save_flags(flags); | 3402 | spin_lock_irqsave(&brd_lock, flags); |
3422 | cli(); | ||
3423 | BRDENABLE(portp->brdnr, portp->pagenr); | 3403 | BRDENABLE(portp->brdnr, portp->pagenr); |
3424 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); | 3404 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); |
3425 | srer = stl_cd1400getreg(portp, SRER); | 3405 | srer = stl_cd1400getreg(portp, SRER); |
@@ -3456,7 +3436,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3456 | portp->sigs &= ~TIOCM_CD; | 3436 | portp->sigs &= ~TIOCM_CD; |
3457 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); | 3437 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); |
3458 | BRDDISABLE(portp->brdnr); | 3438 | BRDDISABLE(portp->brdnr); |
3459 | restore_flags(flags); | 3439 | spin_unlock_irqrestore(&brd_lock, flags); |
3460 | } | 3440 | } |
3461 | 3441 | ||
3462 | /*****************************************************************************/ | 3442 | /*****************************************************************************/ |
@@ -3482,8 +3462,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3482 | if (rts > 0) | 3462 | if (rts > 0) |
3483 | msvr2 = MSVR2_RTS; | 3463 | msvr2 = MSVR2_RTS; |
3484 | 3464 | ||
3485 | save_flags(flags); | 3465 | spin_lock_irqsave(&brd_lock, flags); |
3486 | cli(); | ||
3487 | BRDENABLE(portp->brdnr, portp->pagenr); | 3466 | BRDENABLE(portp->brdnr, portp->pagenr); |
3488 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3467 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3489 | if (rts >= 0) | 3468 | if (rts >= 0) |
@@ -3491,7 +3470,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3491 | if (dtr >= 0) | 3470 | if (dtr >= 0) |
3492 | stl_cd1400setreg(portp, MSVR1, msvr1); | 3471 | stl_cd1400setreg(portp, MSVR1, msvr1); |
3493 | BRDDISABLE(portp->brdnr); | 3472 | BRDDISABLE(portp->brdnr); |
3494 | restore_flags(flags); | 3473 | spin_unlock_irqrestore(&brd_lock, flags); |
3495 | } | 3474 | } |
3496 | 3475 | ||
3497 | /*****************************************************************************/ | 3476 | /*****************************************************************************/ |
@@ -3510,14 +3489,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
3510 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | 3489 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); |
3511 | #endif | 3490 | #endif |
3512 | 3491 | ||
3513 | save_flags(flags); | 3492 | spin_lock_irqsave(&brd_lock, flags); |
3514 | cli(); | ||
3515 | BRDENABLE(portp->brdnr, portp->pagenr); | 3493 | BRDENABLE(portp->brdnr, portp->pagenr); |
3516 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3494 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3517 | msvr1 = stl_cd1400getreg(portp, MSVR1); | 3495 | msvr1 = stl_cd1400getreg(portp, MSVR1); |
3518 | msvr2 = stl_cd1400getreg(portp, MSVR2); | 3496 | msvr2 = stl_cd1400getreg(portp, MSVR2); |
3519 | BRDDISABLE(portp->brdnr); | 3497 | BRDDISABLE(portp->brdnr); |
3520 | restore_flags(flags); | 3498 | spin_unlock_irqrestore(&brd_lock, flags); |
3521 | 3499 | ||
3522 | sigs = 0; | 3500 | sigs = 0; |
3523 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; | 3501 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; |
@@ -3559,15 +3537,14 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
3559 | else if (rx > 0) | 3537 | else if (rx > 0) |
3560 | ccr |= CCR_RXENABLE; | 3538 | ccr |= CCR_RXENABLE; |
3561 | 3539 | ||
3562 | save_flags(flags); | 3540 | spin_lock_irqsave(&brd_lock, flags); |
3563 | cli(); | ||
3564 | BRDENABLE(portp->brdnr, portp->pagenr); | 3541 | BRDENABLE(portp->brdnr, portp->pagenr); |
3565 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3542 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3566 | stl_cd1400ccrwait(portp); | 3543 | stl_cd1400ccrwait(portp); |
3567 | stl_cd1400setreg(portp, CCR, ccr); | 3544 | stl_cd1400setreg(portp, CCR, ccr); |
3568 | stl_cd1400ccrwait(portp); | 3545 | stl_cd1400ccrwait(portp); |
3569 | BRDDISABLE(portp->brdnr); | 3546 | BRDDISABLE(portp->brdnr); |
3570 | restore_flags(flags); | 3547 | spin_unlock_irqrestore(&brd_lock, flags); |
3571 | } | 3548 | } |
3572 | 3549 | ||
3573 | /*****************************************************************************/ | 3550 | /*****************************************************************************/ |
@@ -3599,8 +3576,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3599 | else if (rx > 0) | 3576 | else if (rx > 0) |
3600 | sreron |= SRER_RXDATA; | 3577 | sreron |= SRER_RXDATA; |
3601 | 3578 | ||
3602 | save_flags(flags); | 3579 | spin_lock_irqsave(&brd_lock, flags); |
3603 | cli(); | ||
3604 | BRDENABLE(portp->brdnr, portp->pagenr); | 3580 | BRDENABLE(portp->brdnr, portp->pagenr); |
3605 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3581 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3606 | stl_cd1400setreg(portp, SRER, | 3582 | stl_cd1400setreg(portp, SRER, |
@@ -3608,7 +3584,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3608 | BRDDISABLE(portp->brdnr); | 3584 | BRDDISABLE(portp->brdnr); |
3609 | if (tx > 0) | 3585 | if (tx > 0) |
3610 | set_bit(ASYI_TXBUSY, &portp->istate); | 3586 | set_bit(ASYI_TXBUSY, &portp->istate); |
3611 | restore_flags(flags); | 3587 | spin_unlock_irqrestore(&brd_lock, flags); |
3612 | } | 3588 | } |
3613 | 3589 | ||
3614 | /*****************************************************************************/ | 3590 | /*****************************************************************************/ |
@@ -3624,13 +3600,12 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
3624 | #ifdef DEBUG | 3600 | #ifdef DEBUG |
3625 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3601 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); |
3626 | #endif | 3602 | #endif |
3627 | save_flags(flags); | 3603 | spin_lock_irqsave(&brd_lock, flags); |
3628 | cli(); | ||
3629 | BRDENABLE(portp->brdnr, portp->pagenr); | 3604 | BRDENABLE(portp->brdnr, portp->pagenr); |
3630 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3605 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3631 | stl_cd1400setreg(portp, SRER, 0); | 3606 | stl_cd1400setreg(portp, SRER, 0); |
3632 | BRDDISABLE(portp->brdnr); | 3607 | BRDDISABLE(portp->brdnr); |
3633 | restore_flags(flags); | 3608 | spin_unlock_irqrestore(&brd_lock, flags); |
3634 | } | 3609 | } |
3635 | 3610 | ||
3636 | /*****************************************************************************/ | 3611 | /*****************************************************************************/ |
@@ -3643,8 +3618,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3643 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 3618 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
3644 | #endif | 3619 | #endif |
3645 | 3620 | ||
3646 | save_flags(flags); | 3621 | spin_lock_irqsave(&brd_lock, flags); |
3647 | cli(); | ||
3648 | BRDENABLE(portp->brdnr, portp->pagenr); | 3622 | BRDENABLE(portp->brdnr, portp->pagenr); |
3649 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3623 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3650 | stl_cd1400setreg(portp, SRER, | 3624 | stl_cd1400setreg(portp, SRER, |
@@ -3654,7 +3628,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3654 | portp->brklen = len; | 3628 | portp->brklen = len; |
3655 | if (len == 1) | 3629 | if (len == 1) |
3656 | portp->stats.txbreaks++; | 3630 | portp->stats.txbreaks++; |
3657 | restore_flags(flags); | 3631 | spin_unlock_irqrestore(&brd_lock, flags); |
3658 | } | 3632 | } |
3659 | 3633 | ||
3660 | /*****************************************************************************/ | 3634 | /*****************************************************************************/ |
@@ -3678,8 +3652,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3678 | if (tty == (struct tty_struct *) NULL) | 3652 | if (tty == (struct tty_struct *) NULL) |
3679 | return; | 3653 | return; |
3680 | 3654 | ||
3681 | save_flags(flags); | 3655 | spin_lock_irqsave(&brd_lock, flags); |
3682 | cli(); | ||
3683 | BRDENABLE(portp->brdnr, portp->pagenr); | 3656 | BRDENABLE(portp->brdnr, portp->pagenr); |
3684 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3657 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3685 | 3658 | ||
@@ -3719,7 +3692,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3719 | } | 3692 | } |
3720 | 3693 | ||
3721 | BRDDISABLE(portp->brdnr); | 3694 | BRDDISABLE(portp->brdnr); |
3722 | restore_flags(flags); | 3695 | spin_unlock_irqrestore(&brd_lock, flags); |
3723 | } | 3696 | } |
3724 | 3697 | ||
3725 | /*****************************************************************************/ | 3698 | /*****************************************************************************/ |
@@ -3743,8 +3716,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3743 | if (tty == (struct tty_struct *) NULL) | 3716 | if (tty == (struct tty_struct *) NULL) |
3744 | return; | 3717 | return; |
3745 | 3718 | ||
3746 | save_flags(flags); | 3719 | spin_lock_irqsave(&brd_lock, flags); |
3747 | cli(); | ||
3748 | BRDENABLE(portp->brdnr, portp->pagenr); | 3720 | BRDENABLE(portp->brdnr, portp->pagenr); |
3749 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3721 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3750 | if (state) { | 3722 | if (state) { |
@@ -3759,7 +3731,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3759 | stl_cd1400ccrwait(portp); | 3731 | stl_cd1400ccrwait(portp); |
3760 | } | 3732 | } |
3761 | BRDDISABLE(portp->brdnr); | 3733 | BRDDISABLE(portp->brdnr); |
3762 | restore_flags(flags); | 3734 | spin_unlock_irqrestore(&brd_lock, flags); |
3763 | } | 3735 | } |
3764 | 3736 | ||
3765 | /*****************************************************************************/ | 3737 | /*****************************************************************************/ |
@@ -3775,8 +3747,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3775 | if (portp == (stlport_t *) NULL) | 3747 | if (portp == (stlport_t *) NULL) |
3776 | return; | 3748 | return; |
3777 | 3749 | ||
3778 | save_flags(flags); | 3750 | spin_lock_irqsave(&brd_lock, flags); |
3779 | cli(); | ||
3780 | BRDENABLE(portp->brdnr, portp->pagenr); | 3751 | BRDENABLE(portp->brdnr, portp->pagenr); |
3781 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3752 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3782 | stl_cd1400ccrwait(portp); | 3753 | stl_cd1400ccrwait(portp); |
@@ -3784,7 +3755,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3784 | stl_cd1400ccrwait(portp); | 3755 | stl_cd1400ccrwait(portp); |
3785 | portp->tx.tail = portp->tx.head; | 3756 | portp->tx.tail = portp->tx.head; |
3786 | BRDDISABLE(portp->brdnr); | 3757 | BRDDISABLE(portp->brdnr); |
3787 | restore_flags(flags); | 3758 | spin_unlock_irqrestore(&brd_lock, flags); |
3788 | } | 3759 | } |
3789 | 3760 | ||
3790 | /*****************************************************************************/ | 3761 | /*****************************************************************************/ |
@@ -3823,6 +3794,7 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3823 | (int) panelp, iobase); | 3794 | (int) panelp, iobase); |
3824 | #endif | 3795 | #endif |
3825 | 3796 | ||
3797 | spin_lock(&brd_lock); | ||
3826 | outb(SVRR, iobase); | 3798 | outb(SVRR, iobase); |
3827 | svrtype = inb(iobase + EREG_DATA); | 3799 | svrtype = inb(iobase + EREG_DATA); |
3828 | if (panelp->nrports > 4) { | 3800 | if (panelp->nrports > 4) { |
@@ -3836,6 +3808,8 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3836 | stl_cd1400txisr(panelp, iobase); | 3808 | stl_cd1400txisr(panelp, iobase); |
3837 | else if (svrtype & SVRR_MDM) | 3809 | else if (svrtype & SVRR_MDM) |
3838 | stl_cd1400mdmisr(panelp, iobase); | 3810 | stl_cd1400mdmisr(panelp, iobase); |
3811 | |||
3812 | spin_unlock(&brd_lock); | ||
3839 | } | 3813 | } |
3840 | 3814 | ||
3841 | /*****************************************************************************/ | 3815 | /*****************************************************************************/ |
@@ -4423,8 +4397,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4423 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 4397 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
4424 | #endif | 4398 | #endif |
4425 | 4399 | ||
4426 | save_flags(flags); | 4400 | spin_lock_irqsave(&brd_lock, flags); |
4427 | cli(); | ||
4428 | BRDENABLE(portp->brdnr, portp->pagenr); | 4401 | BRDENABLE(portp->brdnr, portp->pagenr); |
4429 | stl_sc26198setreg(portp, IMR, 0); | 4402 | stl_sc26198setreg(portp, IMR, 0); |
4430 | stl_sc26198updatereg(portp, MR0, mr0); | 4403 | stl_sc26198updatereg(portp, MR0, mr0); |
@@ -4451,7 +4424,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4451 | portp->imr = (portp->imr & ~imroff) | imron; | 4424 | portp->imr = (portp->imr & ~imroff) | imron; |
4452 | stl_sc26198setreg(portp, IMR, portp->imr); | 4425 | stl_sc26198setreg(portp, IMR, portp->imr); |
4453 | BRDDISABLE(portp->brdnr); | 4426 | BRDDISABLE(portp->brdnr); |
4454 | restore_flags(flags); | 4427 | spin_unlock_irqrestore(&brd_lock, flags); |
4455 | } | 4428 | } |
4456 | 4429 | ||
4457 | /*****************************************************************************/ | 4430 | /*****************************************************************************/ |
@@ -4481,13 +4454,12 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
4481 | else if (rts > 0) | 4454 | else if (rts > 0) |
4482 | iopioron |= IPR_RTS; | 4455 | iopioron |= IPR_RTS; |
4483 | 4456 | ||
4484 | save_flags(flags); | 4457 | spin_lock_irqsave(&brd_lock, flags); |
4485 | cli(); | ||
4486 | BRDENABLE(portp->brdnr, portp->pagenr); | 4458 | BRDENABLE(portp->brdnr, portp->pagenr); |
4487 | stl_sc26198setreg(portp, IOPIOR, | 4459 | stl_sc26198setreg(portp, IOPIOR, |
4488 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); | 4460 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); |
4489 | BRDDISABLE(portp->brdnr); | 4461 | BRDDISABLE(portp->brdnr); |
4490 | restore_flags(flags); | 4462 | spin_unlock_irqrestore(&brd_lock, flags); |
4491 | } | 4463 | } |
4492 | 4464 | ||
4493 | /*****************************************************************************/ | 4465 | /*****************************************************************************/ |
@@ -4506,12 +4478,11 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
4506 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | 4478 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); |
4507 | #endif | 4479 | #endif |
4508 | 4480 | ||
4509 | save_flags(flags); | 4481 | spin_lock_irqsave(&brd_lock, flags); |
4510 | cli(); | ||
4511 | BRDENABLE(portp->brdnr, portp->pagenr); | 4482 | BRDENABLE(portp->brdnr, portp->pagenr); |
4512 | ipr = stl_sc26198getreg(portp, IPR); | 4483 | ipr = stl_sc26198getreg(portp, IPR); |
4513 | BRDDISABLE(portp->brdnr); | 4484 | BRDDISABLE(portp->brdnr); |
4514 | restore_flags(flags); | 4485 | spin_unlock_irqrestore(&brd_lock, flags); |
4515 | 4486 | ||
4516 | sigs = 0; | 4487 | sigs = 0; |
4517 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; | 4488 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; |
@@ -4548,13 +4519,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
4548 | else if (rx > 0) | 4519 | else if (rx > 0) |
4549 | ccr |= CR_RXENABLE; | 4520 | ccr |= CR_RXENABLE; |
4550 | 4521 | ||
4551 | save_flags(flags); | 4522 | spin_lock_irqsave(&brd_lock, flags); |
4552 | cli(); | ||
4553 | BRDENABLE(portp->brdnr, portp->pagenr); | 4523 | BRDENABLE(portp->brdnr, portp->pagenr); |
4554 | stl_sc26198setreg(portp, SCCR, ccr); | 4524 | stl_sc26198setreg(portp, SCCR, ccr); |
4555 | BRDDISABLE(portp->brdnr); | 4525 | BRDDISABLE(portp->brdnr); |
4556 | portp->crenable = ccr; | 4526 | portp->crenable = ccr; |
4557 | restore_flags(flags); | 4527 | spin_unlock_irqrestore(&brd_lock, flags); |
4558 | } | 4528 | } |
4559 | 4529 | ||
4560 | /*****************************************************************************/ | 4530 | /*****************************************************************************/ |
@@ -4583,15 +4553,14 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
4583 | else if (rx > 0) | 4553 | else if (rx > 0) |
4584 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; | 4554 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; |
4585 | 4555 | ||
4586 | save_flags(flags); | 4556 | spin_lock_irqsave(&brd_lock, flags); |
4587 | cli(); | ||
4588 | BRDENABLE(portp->brdnr, portp->pagenr); | 4557 | BRDENABLE(portp->brdnr, portp->pagenr); |
4589 | stl_sc26198setreg(portp, IMR, imr); | 4558 | stl_sc26198setreg(portp, IMR, imr); |
4590 | BRDDISABLE(portp->brdnr); | 4559 | BRDDISABLE(portp->brdnr); |
4591 | portp->imr = imr; | 4560 | portp->imr = imr; |
4592 | if (tx > 0) | 4561 | if (tx > 0) |
4593 | set_bit(ASYI_TXBUSY, &portp->istate); | 4562 | set_bit(ASYI_TXBUSY, &portp->istate); |
4594 | restore_flags(flags); | 4563 | spin_unlock_irqrestore(&brd_lock, flags); |
4595 | } | 4564 | } |
4596 | 4565 | ||
4597 | /*****************************************************************************/ | 4566 | /*****************************************************************************/ |
@@ -4608,13 +4577,12 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
4608 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | 4577 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); |
4609 | #endif | 4578 | #endif |
4610 | 4579 | ||
4611 | save_flags(flags); | 4580 | spin_lock_irqsave(&brd_lock, flags); |
4612 | cli(); | ||
4613 | BRDENABLE(portp->brdnr, portp->pagenr); | 4581 | BRDENABLE(portp->brdnr, portp->pagenr); |
4614 | portp->imr = 0; | 4582 | portp->imr = 0; |
4615 | stl_sc26198setreg(portp, IMR, 0); | 4583 | stl_sc26198setreg(portp, IMR, 0); |
4616 | BRDDISABLE(portp->brdnr); | 4584 | BRDDISABLE(portp->brdnr); |
4617 | restore_flags(flags); | 4585 | spin_unlock_irqrestore(&brd_lock, flags); |
4618 | } | 4586 | } |
4619 | 4587 | ||
4620 | /*****************************************************************************/ | 4588 | /*****************************************************************************/ |
@@ -4627,8 +4595,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4627 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 4595 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
4628 | #endif | 4596 | #endif |
4629 | 4597 | ||
4630 | save_flags(flags); | 4598 | spin_lock_irqsave(&brd_lock, flags); |
4631 | cli(); | ||
4632 | BRDENABLE(portp->brdnr, portp->pagenr); | 4599 | BRDENABLE(portp->brdnr, portp->pagenr); |
4633 | if (len == 1) { | 4600 | if (len == 1) { |
4634 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4601 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
@@ -4637,7 +4604,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4637 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4604 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
4638 | } | 4605 | } |
4639 | BRDDISABLE(portp->brdnr); | 4606 | BRDDISABLE(portp->brdnr); |
4640 | restore_flags(flags); | 4607 | spin_unlock_irqrestore(&brd_lock, flags); |
4641 | } | 4608 | } |
4642 | 4609 | ||
4643 | /*****************************************************************************/ | 4610 | /*****************************************************************************/ |
@@ -4662,8 +4629,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4662 | if (tty == (struct tty_struct *) NULL) | 4629 | if (tty == (struct tty_struct *) NULL) |
4663 | return; | 4630 | return; |
4664 | 4631 | ||
4665 | save_flags(flags); | 4632 | spin_lock_irqsave(&brd_lock, flags); |
4666 | cli(); | ||
4667 | BRDENABLE(portp->brdnr, portp->pagenr); | 4633 | BRDENABLE(portp->brdnr, portp->pagenr); |
4668 | 4634 | ||
4669 | if (state) { | 4635 | if (state) { |
@@ -4709,7 +4675,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4709 | } | 4675 | } |
4710 | 4676 | ||
4711 | BRDDISABLE(portp->brdnr); | 4677 | BRDDISABLE(portp->brdnr); |
4712 | restore_flags(flags); | 4678 | spin_unlock_irqrestore(&brd_lock, flags); |
4713 | } | 4679 | } |
4714 | 4680 | ||
4715 | /*****************************************************************************/ | 4681 | /*****************************************************************************/ |
@@ -4734,8 +4700,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4734 | if (tty == (struct tty_struct *) NULL) | 4700 | if (tty == (struct tty_struct *) NULL) |
4735 | return; | 4701 | return; |
4736 | 4702 | ||
4737 | save_flags(flags); | 4703 | spin_lock_irqsave(&brd_lock, flags); |
4738 | cli(); | ||
4739 | BRDENABLE(portp->brdnr, portp->pagenr); | 4704 | BRDENABLE(portp->brdnr, portp->pagenr); |
4740 | if (state) { | 4705 | if (state) { |
4741 | mr0 = stl_sc26198getreg(portp, MR0); | 4706 | mr0 = stl_sc26198getreg(portp, MR0); |
@@ -4755,7 +4720,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4755 | stl_sc26198setreg(portp, MR0, mr0); | 4720 | stl_sc26198setreg(portp, MR0, mr0); |
4756 | } | 4721 | } |
4757 | BRDDISABLE(portp->brdnr); | 4722 | BRDDISABLE(portp->brdnr); |
4758 | restore_flags(flags); | 4723 | spin_unlock_irqrestore(&brd_lock, flags); |
4759 | } | 4724 | } |
4760 | 4725 | ||
4761 | /*****************************************************************************/ | 4726 | /*****************************************************************************/ |
@@ -4771,14 +4736,13 @@ static void stl_sc26198flush(stlport_t *portp) | |||
4771 | if (portp == (stlport_t *) NULL) | 4736 | if (portp == (stlport_t *) NULL) |
4772 | return; | 4737 | return; |
4773 | 4738 | ||
4774 | save_flags(flags); | 4739 | spin_lock_irqsave(&brd_lock, flags); |
4775 | cli(); | ||
4776 | BRDENABLE(portp->brdnr, portp->pagenr); | 4740 | BRDENABLE(portp->brdnr, portp->pagenr); |
4777 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); | 4741 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); |
4778 | stl_sc26198setreg(portp, SCCR, portp->crenable); | 4742 | stl_sc26198setreg(portp, SCCR, portp->crenable); |
4779 | BRDDISABLE(portp->brdnr); | 4743 | BRDDISABLE(portp->brdnr); |
4780 | portp->tx.tail = portp->tx.head; | 4744 | portp->tx.tail = portp->tx.head; |
4781 | restore_flags(flags); | 4745 | spin_unlock_irqrestore(&brd_lock, flags); |
4782 | } | 4746 | } |
4783 | 4747 | ||
4784 | /*****************************************************************************/ | 4748 | /*****************************************************************************/ |
@@ -4805,12 +4769,11 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
4805 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4769 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
4806 | return 1; | 4770 | return 1; |
4807 | 4771 | ||
4808 | save_flags(flags); | 4772 | spin_lock_irqsave(&brd_lock, flags); |
4809 | cli(); | ||
4810 | BRDENABLE(portp->brdnr, portp->pagenr); | 4773 | BRDENABLE(portp->brdnr, portp->pagenr); |
4811 | sr = stl_sc26198getreg(portp, SR); | 4774 | sr = stl_sc26198getreg(portp, SR); |
4812 | BRDDISABLE(portp->brdnr); | 4775 | BRDDISABLE(portp->brdnr); |
4813 | restore_flags(flags); | 4776 | spin_unlock_irqrestore(&brd_lock, flags); |
4814 | 4777 | ||
4815 | return (sr & SR_TXEMPTY) ? 0 : 1; | 4778 | return (sr & SR_TXEMPTY) ? 0 : 1; |
4816 | } | 4779 | } |
@@ -4868,6 +4831,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4868 | stlport_t *portp; | 4831 | stlport_t *portp; |
4869 | unsigned int iack; | 4832 | unsigned int iack; |
4870 | 4833 | ||
4834 | spin_lock(&brd_lock); | ||
4835 | |||
4871 | /* | 4836 | /* |
4872 | * Work around bug in sc26198 chip... Cannot have A6 address | 4837 | * Work around bug in sc26198 chip... Cannot have A6 address |
4873 | * line of UART high, else iack will be returned as 0. | 4838 | * line of UART high, else iack will be returned as 0. |
@@ -4883,6 +4848,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4883 | stl_sc26198txisr(portp); | 4848 | stl_sc26198txisr(portp); |
4884 | else | 4849 | else |
4885 | stl_sc26198otherisr(portp, iack); | 4850 | stl_sc26198otherisr(portp, iack); |
4851 | |||
4852 | spin_unlock(&brd_lock); | ||
4886 | } | 4853 | } |
4887 | 4854 | ||
4888 | /*****************************************************************************/ | 4855 | /*****************************************************************************/ |