diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-06-27 05:54:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-27 20:32:40 -0400 |
commit | b65b5b59f98aa317df399318b0b2770f50732d3c (patch) | |
tree | dff57f7773b54b3336e56ab84aa8b4d820797572 | |
parent | 33979734cd35ae0624337cdbc529921e4350d96f (diff) |
[PATCH] stallion clean up
There are two locking sets involved. One locks the board mappings and the
other is the tty open/close locking. The low level code was clearly
designed to be ported to OS's with spin locks already so pretty much comes
out in the wash
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/char/stallion.c | 208 |
1 files changed, 86 insertions, 122 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index a9c5a7230f89..bf361a5ba70d 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -141,15 +141,6 @@ static char *stl_drvversion = "5.6.0"; | |||
141 | static struct tty_driver *stl_serial; | 141 | static struct tty_driver *stl_serial; |
142 | 142 | ||
143 | /* | 143 | /* |
144 | * We will need to allocate a temporary write buffer for chars that | ||
145 | * come direct from user space. The problem is that a copy from user | ||
146 | * space might cause a page fault (typically on a system that is | ||
147 | * swapping!). All ports will share one buffer - since if the system | ||
148 | * is already swapping a shared buffer won't make things any worse. | ||
149 | */ | ||
150 | static char *stl_tmpwritebuf; | ||
151 | |||
152 | /* | ||
153 | * Define a local default termios struct. All ports will be created | 144 | * Define a local default termios struct. All ports will be created |
154 | * with this termios initially. Basically all it defines is a raw port | 145 | * with this termios initially. Basically all it defines is a raw port |
155 | * at 9600, 8 data bits, 1 stop bit. | 146 | * at 9600, 8 data bits, 1 stop bit. |
@@ -363,6 +354,14 @@ static unsigned char stl_vecmap[] = { | |||
363 | }; | 354 | }; |
364 | 355 | ||
365 | /* | 356 | /* |
357 | * Lock ordering is that you may not take stallion_lock holding | ||
358 | * brd_lock. | ||
359 | */ | ||
360 | |||
361 | static spinlock_t brd_lock; /* Guard the board mapping */ | ||
362 | static spinlock_t stallion_lock; /* Guard the tty driver */ | ||
363 | |||
364 | /* | ||
366 | * Set up enable and disable macros for the ECH boards. They require | 365 | * Set up enable and disable macros for the ECH boards. They require |
367 | * the secondary io address space to be activated and deactivated. | 366 | * the secondary io address space to be activated and deactivated. |
368 | * This way all ECH boards can share their secondary io region. | 367 | * This way all ECH boards can share their secondary io region. |
@@ -725,17 +724,7 @@ static struct class *stallion_class; | |||
725 | 724 | ||
726 | static int __init stallion_module_init(void) | 725 | static int __init stallion_module_init(void) |
727 | { | 726 | { |
728 | unsigned long flags; | ||
729 | |||
730 | #ifdef DEBUG | ||
731 | printk("init_module()\n"); | ||
732 | #endif | ||
733 | |||
734 | save_flags(flags); | ||
735 | cli(); | ||
736 | stl_init(); | 727 | stl_init(); |
737 | restore_flags(flags); | ||
738 | |||
739 | return 0; | 728 | return 0; |
740 | } | 729 | } |
741 | 730 | ||
@@ -746,7 +735,6 @@ static void __exit stallion_module_exit(void) | |||
746 | stlbrd_t *brdp; | 735 | stlbrd_t *brdp; |
747 | stlpanel_t *panelp; | 736 | stlpanel_t *panelp; |
748 | stlport_t *portp; | 737 | stlport_t *portp; |
749 | unsigned long flags; | ||
750 | int i, j, k; | 738 | int i, j, k; |
751 | 739 | ||
752 | #ifdef DEBUG | 740 | #ifdef DEBUG |
@@ -756,9 +744,6 @@ static void __exit stallion_module_exit(void) | |||
756 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | 744 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, |
757 | stl_drvversion); | 745 | stl_drvversion); |
758 | 746 | ||
759 | save_flags(flags); | ||
760 | cli(); | ||
761 | |||
762 | /* | 747 | /* |
763 | * Free up all allocated resources used by the ports. This includes | 748 | * Free up all allocated resources used by the ports. This includes |
764 | * memory and interrupts. As part of this process we will also do | 749 | * memory and interrupts. As part of this process we will also do |
@@ -770,7 +755,6 @@ static void __exit stallion_module_exit(void) | |||
770 | if (i) { | 755 | if (i) { |
771 | printk("STALLION: failed to un-register tty driver, " | 756 | printk("STALLION: failed to un-register tty driver, " |
772 | "errno=%d\n", -i); | 757 | "errno=%d\n", -i); |
773 | restore_flags(flags); | ||
774 | return; | 758 | return; |
775 | } | 759 | } |
776 | for (i = 0; i < 4; i++) { | 760 | for (i = 0; i < 4; i++) { |
@@ -783,8 +767,6 @@ static void __exit stallion_module_exit(void) | |||
783 | "errno=%d\n", -i); | 767 | "errno=%d\n", -i); |
784 | class_destroy(stallion_class); | 768 | class_destroy(stallion_class); |
785 | 769 | ||
786 | kfree(stl_tmpwritebuf); | ||
787 | |||
788 | for (i = 0; (i < stl_nrbrds); i++) { | 770 | for (i = 0; (i < stl_nrbrds); i++) { |
789 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | 771 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) |
790 | continue; | 772 | continue; |
@@ -814,8 +796,6 @@ static void __exit stallion_module_exit(void) | |||
814 | kfree(brdp); | 796 | kfree(brdp); |
815 | stl_brds[i] = (stlbrd_t *) NULL; | 797 | stl_brds[i] = (stlbrd_t *) NULL; |
816 | } | 798 | } |
817 | |||
818 | restore_flags(flags); | ||
819 | } | 799 | } |
820 | 800 | ||
821 | module_init(stallion_module_init); | 801 | module_init(stallion_module_init); |
@@ -948,7 +928,7 @@ static stlbrd_t *stl_allocbrd(void) | |||
948 | 928 | ||
949 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 929 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
950 | if (!brdp) { | 930 | if (!brdp) { |
951 | printk("STALLION: failed to allocate memory (size=%d)\n", | 931 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
952 | sizeof(stlbrd_t)); | 932 | sizeof(stlbrd_t)); |
953 | return NULL; | 933 | return NULL; |
954 | } | 934 | } |
@@ -1066,16 +1046,17 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1066 | rc = 0; | 1046 | rc = 0; |
1067 | doclocal = 0; | 1047 | doclocal = 0; |
1068 | 1048 | ||
1049 | spin_lock_irqsave(&stallion_lock, flags); | ||
1050 | |||
1069 | if (portp->tty->termios->c_cflag & CLOCAL) | 1051 | if (portp->tty->termios->c_cflag & CLOCAL) |
1070 | doclocal++; | 1052 | doclocal++; |
1071 | 1053 | ||
1072 | save_flags(flags); | ||
1073 | cli(); | ||
1074 | portp->openwaitcnt++; | 1054 | portp->openwaitcnt++; |
1075 | if (! tty_hung_up_p(filp)) | 1055 | if (! tty_hung_up_p(filp)) |
1076 | portp->refcount--; | 1056 | portp->refcount--; |
1077 | 1057 | ||
1078 | for (;;) { | 1058 | for (;;) { |
1059 | /* Takes brd_lock internally */ | ||
1079 | stl_setsignals(portp, 1, 1); | 1060 | stl_setsignals(portp, 1, 1); |
1080 | if (tty_hung_up_p(filp) || | 1061 | if (tty_hung_up_p(filp) || |
1081 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { | 1062 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { |
@@ -1093,13 +1074,14 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1093 | rc = -ERESTARTSYS; | 1074 | rc = -ERESTARTSYS; |
1094 | break; | 1075 | break; |
1095 | } | 1076 | } |
1077 | /* FIXME */ | ||
1096 | interruptible_sleep_on(&portp->open_wait); | 1078 | interruptible_sleep_on(&portp->open_wait); |
1097 | } | 1079 | } |
1098 | 1080 | ||
1099 | if (! tty_hung_up_p(filp)) | 1081 | if (! tty_hung_up_p(filp)) |
1100 | portp->refcount++; | 1082 | portp->refcount++; |
1101 | portp->openwaitcnt--; | 1083 | portp->openwaitcnt--; |
1102 | restore_flags(flags); | 1084 | spin_unlock_irqrestore(&stallion_lock, flags); |
1103 | 1085 | ||
1104 | return rc; | 1086 | return rc; |
1105 | } | 1087 | } |
@@ -1119,16 +1101,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1119 | if (portp == (stlport_t *) NULL) | 1101 | if (portp == (stlport_t *) NULL) |
1120 | return; | 1102 | return; |
1121 | 1103 | ||
1122 | save_flags(flags); | 1104 | spin_lock_irqsave(&stallion_lock, flags); |
1123 | cli(); | ||
1124 | if (tty_hung_up_p(filp)) { | 1105 | if (tty_hung_up_p(filp)) { |
1125 | restore_flags(flags); | 1106 | spin_unlock_irqrestore(&stallion_lock, flags); |
1126 | return; | 1107 | return; |
1127 | } | 1108 | } |
1128 | if ((tty->count == 1) && (portp->refcount != 1)) | 1109 | if ((tty->count == 1) && (portp->refcount != 1)) |
1129 | portp->refcount = 1; | 1110 | portp->refcount = 1; |
1130 | if (portp->refcount-- > 1) { | 1111 | if (portp->refcount-- > 1) { |
1131 | restore_flags(flags); | 1112 | spin_unlock_irqrestore(&stallion_lock, flags); |
1132 | return; | 1113 | return; |
1133 | } | 1114 | } |
1134 | 1115 | ||
@@ -1142,11 +1123,18 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1142 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | 1123 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) |
1143 | */ | 1124 | */ |
1144 | tty->closing = 1; | 1125 | tty->closing = 1; |
1126 | |||
1127 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1128 | |||
1145 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1129 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1146 | tty_wait_until_sent(tty, portp->closing_wait); | 1130 | tty_wait_until_sent(tty, portp->closing_wait); |
1147 | stl_waituntilsent(tty, (HZ / 2)); | 1131 | stl_waituntilsent(tty, (HZ / 2)); |
1148 | 1132 | ||
1133 | |||
1134 | spin_lock_irqsave(&stallion_lock, flags); | ||
1149 | portp->flags &= ~ASYNC_INITIALIZED; | 1135 | portp->flags &= ~ASYNC_INITIALIZED; |
1136 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1137 | |||
1150 | stl_disableintrs(portp); | 1138 | stl_disableintrs(portp); |
1151 | if (tty->termios->c_cflag & HUPCL) | 1139 | if (tty->termios->c_cflag & HUPCL) |
1152 | stl_setsignals(portp, 0, 0); | 1140 | stl_setsignals(portp, 0, 0); |
@@ -1173,7 +1161,6 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1173 | 1161 | ||
1174 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1162 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1175 | wake_up_interruptible(&portp->close_wait); | 1163 | wake_up_interruptible(&portp->close_wait); |
1176 | restore_flags(flags); | ||
1177 | } | 1164 | } |
1178 | 1165 | ||
1179 | /*****************************************************************************/ | 1166 | /*****************************************************************************/ |
@@ -1195,9 +1182,6 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1195 | (int) tty, (int) buf, count); | 1182 | (int) tty, (int) buf, count); |
1196 | #endif | 1183 | #endif |
1197 | 1184 | ||
1198 | if ((tty == (struct tty_struct *) NULL) || | ||
1199 | (stl_tmpwritebuf == (char *) NULL)) | ||
1200 | return 0; | ||
1201 | portp = tty->driver_data; | 1185 | portp = tty->driver_data; |
1202 | if (portp == (stlport_t *) NULL) | 1186 | if (portp == (stlport_t *) NULL) |
1203 | return 0; | 1187 | return 0; |
@@ -1302,11 +1286,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1302 | if (portp->tx.buf == (char *) NULL) | 1286 | if (portp->tx.buf == (char *) NULL) |
1303 | return; | 1287 | return; |
1304 | 1288 | ||
1305 | #if 0 | ||
1306 | if (tty->stopped || tty->hw_stopped || | ||
1307 | (portp->tx.head == portp->tx.tail)) | ||
1308 | return; | ||
1309 | #endif | ||
1310 | stl_startrxtx(portp, -1, 1); | 1289 | stl_startrxtx(portp, -1, 1); |
1311 | } | 1290 | } |
1312 | 1291 | ||
@@ -1977,12 +1956,14 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
1977 | unsigned int iobase; | 1956 | unsigned int iobase; |
1978 | int handled = 0; | 1957 | int handled = 0; |
1979 | 1958 | ||
1959 | spin_lock(&brd_lock); | ||
1980 | panelp = brdp->panels[0]; | 1960 | panelp = brdp->panels[0]; |
1981 | iobase = panelp->iobase; | 1961 | iobase = panelp->iobase; |
1982 | while (inb(brdp->iostatus) & EIO_INTRPEND) { | 1962 | while (inb(brdp->iostatus) & EIO_INTRPEND) { |
1983 | handled = 1; | 1963 | handled = 1; |
1984 | (* panelp->isr)(panelp, iobase); | 1964 | (* panelp->isr)(panelp, iobase); |
1985 | } | 1965 | } |
1966 | spin_unlock(&brd_lock); | ||
1986 | return handled; | 1967 | return handled; |
1987 | } | 1968 | } |
1988 | 1969 | ||
@@ -2168,7 +2149,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2168 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 2149 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
2169 | if (!portp) { | 2150 | if (!portp) { |
2170 | printk("STALLION: failed to allocate memory " | 2151 | printk("STALLION: failed to allocate memory " |
2171 | "(size=%d)\n", sizeof(stlport_t)); | 2152 | "(size=%Zd)\n", sizeof(stlport_t)); |
2172 | break; | 2153 | break; |
2173 | } | 2154 | } |
2174 | 2155 | ||
@@ -2304,7 +2285,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2304 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2285 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2305 | if (!panelp) { | 2286 | if (!panelp) { |
2306 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2287 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2307 | "(size=%d)\n", sizeof(stlpanel_t)); | 2288 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2308 | return -ENOMEM; | 2289 | return -ENOMEM; |
2309 | } | 2290 | } |
2310 | 2291 | ||
@@ -2478,7 +2459,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2478 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2459 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2479 | if (!panelp) { | 2460 | if (!panelp) { |
2480 | printk("STALLION: failed to allocate memory " | 2461 | printk("STALLION: failed to allocate memory " |
2481 | "(size=%d)\n", sizeof(stlpanel_t)); | 2462 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2482 | break; | 2463 | break; |
2483 | } | 2464 | } |
2484 | panelp->magic = STL_PANELMAGIC; | 2465 | panelp->magic = STL_PANELMAGIC; |
@@ -2879,8 +2860,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2879 | portp->stats.lflags = 0; | 2860 | portp->stats.lflags = 0; |
2880 | portp->stats.rxbuffered = 0; | 2861 | portp->stats.rxbuffered = 0; |
2881 | 2862 | ||
2882 | save_flags(flags); | 2863 | spin_lock_irqsave(&stallion_lock, flags); |
2883 | cli(); | ||
2884 | if (portp->tty != (struct tty_struct *) NULL) { | 2864 | if (portp->tty != (struct tty_struct *) NULL) { |
2885 | if (portp->tty->driver_data == portp) { | 2865 | if (portp->tty->driver_data == portp) { |
2886 | portp->stats.ttystate = portp->tty->flags; | 2866 | portp->stats.ttystate = portp->tty->flags; |
@@ -2894,7 +2874,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2894 | } | 2874 | } |
2895 | } | 2875 | } |
2896 | } | 2876 | } |
2897 | restore_flags(flags); | 2877 | spin_unlock_irqrestore(&stallion_lock, flags); |
2898 | 2878 | ||
2899 | head = portp->tx.head; | 2879 | head = portp->tx.head; |
2900 | tail = portp->tx.tail; | 2880 | tail = portp->tx.tail; |
@@ -3056,14 +3036,6 @@ static int __init stl_init(void) | |||
3056 | return -1; | 3036 | return -1; |
3057 | 3037 | ||
3058 | /* | 3038 | /* |
3059 | * Allocate a temporary write buffer. | ||
3060 | */ | ||
3061 | stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
3062 | if (!stl_tmpwritebuf) | ||
3063 | printk("STALLION: failed to allocate memory (size=%d)\n", | ||
3064 | STL_TXBUFSIZE); | ||
3065 | |||
3066 | /* | ||
3067 | * Set up a character driver for per board stuff. This is mainly used | 3039 | * Set up a character driver for per board stuff. This is mainly used |
3068 | * to do stats ioctls on the ports. | 3040 | * to do stats ioctls on the ports. |
3069 | */ | 3041 | */ |
@@ -3147,11 +3119,13 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3147 | unsigned int gfrcr; | 3119 | unsigned int gfrcr; |
3148 | int chipmask, i, j; | 3120 | int chipmask, i, j; |
3149 | int nrchips, uartaddr, ioaddr; | 3121 | int nrchips, uartaddr, ioaddr; |
3122 | unsigned long flags; | ||
3150 | 3123 | ||
3151 | #ifdef DEBUG | 3124 | #ifdef DEBUG |
3152 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | 3125 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); |
3153 | #endif | 3126 | #endif |
3154 | 3127 | ||
3128 | spin_lock_irqsave(&brd_lock, flags); | ||
3155 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3129 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
3156 | 3130 | ||
3157 | /* | 3131 | /* |
@@ -3189,6 +3163,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3189 | } | 3163 | } |
3190 | 3164 | ||
3191 | BRDDISABLE(panelp->brdnr); | 3165 | BRDDISABLE(panelp->brdnr); |
3166 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3192 | return chipmask; | 3167 | return chipmask; |
3193 | } | 3168 | } |
3194 | 3169 | ||
@@ -3200,6 +3175,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3200 | 3175 | ||
3201 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 3176 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) |
3202 | { | 3177 | { |
3178 | unsigned long flags; | ||
3203 | #ifdef DEBUG | 3179 | #ifdef DEBUG |
3204 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3180 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", |
3205 | (int) brdp, (int) panelp, (int) portp); | 3181 | (int) brdp, (int) panelp, (int) portp); |
@@ -3209,6 +3185,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3209 | (portp == (stlport_t *) NULL)) | 3185 | (portp == (stlport_t *) NULL)) |
3210 | return; | 3186 | return; |
3211 | 3187 | ||
3188 | spin_lock_irqsave(&brd_lock, flags); | ||
3212 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || | 3189 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || |
3213 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); | 3190 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); |
3214 | portp->uartaddr = (portp->portnr & 0x04) << 5; | 3191 | portp->uartaddr = (portp->portnr & 0x04) << 5; |
@@ -3219,6 +3196,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3219 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); | 3196 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); |
3220 | portp->hwid = stl_cd1400getreg(portp, GFRCR); | 3197 | portp->hwid = stl_cd1400getreg(portp, GFRCR); |
3221 | BRDDISABLE(portp->brdnr); | 3198 | BRDDISABLE(portp->brdnr); |
3199 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3222 | } | 3200 | } |
3223 | 3201 | ||
3224 | /*****************************************************************************/ | 3202 | /*****************************************************************************/ |
@@ -3428,8 +3406,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3428 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3406 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
3429 | #endif | 3407 | #endif |
3430 | 3408 | ||
3431 | save_flags(flags); | 3409 | spin_lock_irqsave(&brd_lock, flags); |
3432 | cli(); | ||
3433 | BRDENABLE(portp->brdnr, portp->pagenr); | 3410 | BRDENABLE(portp->brdnr, portp->pagenr); |
3434 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); | 3411 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); |
3435 | srer = stl_cd1400getreg(portp, SRER); | 3412 | srer = stl_cd1400getreg(portp, SRER); |
@@ -3466,7 +3443,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3466 | portp->sigs &= ~TIOCM_CD; | 3443 | portp->sigs &= ~TIOCM_CD; |
3467 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); | 3444 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); |
3468 | BRDDISABLE(portp->brdnr); | 3445 | BRDDISABLE(portp->brdnr); |
3469 | restore_flags(flags); | 3446 | spin_unlock_irqrestore(&brd_lock, flags); |
3470 | } | 3447 | } |
3471 | 3448 | ||
3472 | /*****************************************************************************/ | 3449 | /*****************************************************************************/ |
@@ -3492,8 +3469,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3492 | if (rts > 0) | 3469 | if (rts > 0) |
3493 | msvr2 = MSVR2_RTS; | 3470 | msvr2 = MSVR2_RTS; |
3494 | 3471 | ||
3495 | save_flags(flags); | 3472 | spin_lock_irqsave(&brd_lock, flags); |
3496 | cli(); | ||
3497 | BRDENABLE(portp->brdnr, portp->pagenr); | 3473 | BRDENABLE(portp->brdnr, portp->pagenr); |
3498 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3474 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3499 | if (rts >= 0) | 3475 | if (rts >= 0) |
@@ -3501,7 +3477,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3501 | if (dtr >= 0) | 3477 | if (dtr >= 0) |
3502 | stl_cd1400setreg(portp, MSVR1, msvr1); | 3478 | stl_cd1400setreg(portp, MSVR1, msvr1); |
3503 | BRDDISABLE(portp->brdnr); | 3479 | BRDDISABLE(portp->brdnr); |
3504 | restore_flags(flags); | 3480 | spin_unlock_irqrestore(&brd_lock, flags); |
3505 | } | 3481 | } |
3506 | 3482 | ||
3507 | /*****************************************************************************/ | 3483 | /*****************************************************************************/ |
@@ -3520,14 +3496,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
3520 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | 3496 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); |
3521 | #endif | 3497 | #endif |
3522 | 3498 | ||
3523 | save_flags(flags); | 3499 | spin_lock_irqsave(&brd_lock, flags); |
3524 | cli(); | ||
3525 | BRDENABLE(portp->brdnr, portp->pagenr); | 3500 | BRDENABLE(portp->brdnr, portp->pagenr); |
3526 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3501 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3527 | msvr1 = stl_cd1400getreg(portp, MSVR1); | 3502 | msvr1 = stl_cd1400getreg(portp, MSVR1); |
3528 | msvr2 = stl_cd1400getreg(portp, MSVR2); | 3503 | msvr2 = stl_cd1400getreg(portp, MSVR2); |
3529 | BRDDISABLE(portp->brdnr); | 3504 | BRDDISABLE(portp->brdnr); |
3530 | restore_flags(flags); | 3505 | spin_unlock_irqrestore(&brd_lock, flags); |
3531 | 3506 | ||
3532 | sigs = 0; | 3507 | sigs = 0; |
3533 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; | 3508 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; |
@@ -3569,15 +3544,14 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
3569 | else if (rx > 0) | 3544 | else if (rx > 0) |
3570 | ccr |= CCR_RXENABLE; | 3545 | ccr |= CCR_RXENABLE; |
3571 | 3546 | ||
3572 | save_flags(flags); | 3547 | spin_lock_irqsave(&brd_lock, flags); |
3573 | cli(); | ||
3574 | BRDENABLE(portp->brdnr, portp->pagenr); | 3548 | BRDENABLE(portp->brdnr, portp->pagenr); |
3575 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3549 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3576 | stl_cd1400ccrwait(portp); | 3550 | stl_cd1400ccrwait(portp); |
3577 | stl_cd1400setreg(portp, CCR, ccr); | 3551 | stl_cd1400setreg(portp, CCR, ccr); |
3578 | stl_cd1400ccrwait(portp); | 3552 | stl_cd1400ccrwait(portp); |
3579 | BRDDISABLE(portp->brdnr); | 3553 | BRDDISABLE(portp->brdnr); |
3580 | restore_flags(flags); | 3554 | spin_unlock_irqrestore(&brd_lock, flags); |
3581 | } | 3555 | } |
3582 | 3556 | ||
3583 | /*****************************************************************************/ | 3557 | /*****************************************************************************/ |
@@ -3609,8 +3583,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3609 | else if (rx > 0) | 3583 | else if (rx > 0) |
3610 | sreron |= SRER_RXDATA; | 3584 | sreron |= SRER_RXDATA; |
3611 | 3585 | ||
3612 | save_flags(flags); | 3586 | spin_lock_irqsave(&brd_lock, flags); |
3613 | cli(); | ||
3614 | BRDENABLE(portp->brdnr, portp->pagenr); | 3587 | BRDENABLE(portp->brdnr, portp->pagenr); |
3615 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3588 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3616 | stl_cd1400setreg(portp, SRER, | 3589 | stl_cd1400setreg(portp, SRER, |
@@ -3618,7 +3591,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3618 | BRDDISABLE(portp->brdnr); | 3591 | BRDDISABLE(portp->brdnr); |
3619 | if (tx > 0) | 3592 | if (tx > 0) |
3620 | set_bit(ASYI_TXBUSY, &portp->istate); | 3593 | set_bit(ASYI_TXBUSY, &portp->istate); |
3621 | restore_flags(flags); | 3594 | spin_unlock_irqrestore(&brd_lock, flags); |
3622 | } | 3595 | } |
3623 | 3596 | ||
3624 | /*****************************************************************************/ | 3597 | /*****************************************************************************/ |
@@ -3634,13 +3607,12 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
3634 | #ifdef DEBUG | 3607 | #ifdef DEBUG |
3635 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3608 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); |
3636 | #endif | 3609 | #endif |
3637 | save_flags(flags); | 3610 | spin_lock_irqsave(&brd_lock, flags); |
3638 | cli(); | ||
3639 | BRDENABLE(portp->brdnr, portp->pagenr); | 3611 | BRDENABLE(portp->brdnr, portp->pagenr); |
3640 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3612 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3641 | stl_cd1400setreg(portp, SRER, 0); | 3613 | stl_cd1400setreg(portp, SRER, 0); |
3642 | BRDDISABLE(portp->brdnr); | 3614 | BRDDISABLE(portp->brdnr); |
3643 | restore_flags(flags); | 3615 | spin_unlock_irqrestore(&brd_lock, flags); |
3644 | } | 3616 | } |
3645 | 3617 | ||
3646 | /*****************************************************************************/ | 3618 | /*****************************************************************************/ |
@@ -3653,8 +3625,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3653 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 3625 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
3654 | #endif | 3626 | #endif |
3655 | 3627 | ||
3656 | save_flags(flags); | 3628 | spin_lock_irqsave(&brd_lock, flags); |
3657 | cli(); | ||
3658 | BRDENABLE(portp->brdnr, portp->pagenr); | 3629 | BRDENABLE(portp->brdnr, portp->pagenr); |
3659 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3630 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3660 | stl_cd1400setreg(portp, SRER, | 3631 | stl_cd1400setreg(portp, SRER, |
@@ -3664,7 +3635,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3664 | portp->brklen = len; | 3635 | portp->brklen = len; |
3665 | if (len == 1) | 3636 | if (len == 1) |
3666 | portp->stats.txbreaks++; | 3637 | portp->stats.txbreaks++; |
3667 | restore_flags(flags); | 3638 | spin_unlock_irqrestore(&brd_lock, flags); |
3668 | } | 3639 | } |
3669 | 3640 | ||
3670 | /*****************************************************************************/ | 3641 | /*****************************************************************************/ |
@@ -3688,8 +3659,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3688 | if (tty == (struct tty_struct *) NULL) | 3659 | if (tty == (struct tty_struct *) NULL) |
3689 | return; | 3660 | return; |
3690 | 3661 | ||
3691 | save_flags(flags); | 3662 | spin_lock_irqsave(&brd_lock, flags); |
3692 | cli(); | ||
3693 | BRDENABLE(portp->brdnr, portp->pagenr); | 3663 | BRDENABLE(portp->brdnr, portp->pagenr); |
3694 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3664 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3695 | 3665 | ||
@@ -3729,7 +3699,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3729 | } | 3699 | } |
3730 | 3700 | ||
3731 | BRDDISABLE(portp->brdnr); | 3701 | BRDDISABLE(portp->brdnr); |
3732 | restore_flags(flags); | 3702 | spin_unlock_irqrestore(&brd_lock, flags); |
3733 | } | 3703 | } |
3734 | 3704 | ||
3735 | /*****************************************************************************/ | 3705 | /*****************************************************************************/ |
@@ -3753,8 +3723,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3753 | if (tty == (struct tty_struct *) NULL) | 3723 | if (tty == (struct tty_struct *) NULL) |
3754 | return; | 3724 | return; |
3755 | 3725 | ||
3756 | save_flags(flags); | 3726 | spin_lock_irqsave(&brd_lock, flags); |
3757 | cli(); | ||
3758 | BRDENABLE(portp->brdnr, portp->pagenr); | 3727 | BRDENABLE(portp->brdnr, portp->pagenr); |
3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3728 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3760 | if (state) { | 3729 | if (state) { |
@@ -3769,7 +3738,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3769 | stl_cd1400ccrwait(portp); | 3738 | stl_cd1400ccrwait(portp); |
3770 | } | 3739 | } |
3771 | BRDDISABLE(portp->brdnr); | 3740 | BRDDISABLE(portp->brdnr); |
3772 | restore_flags(flags); | 3741 | spin_unlock_irqrestore(&brd_lock, flags); |
3773 | } | 3742 | } |
3774 | 3743 | ||
3775 | /*****************************************************************************/ | 3744 | /*****************************************************************************/ |
@@ -3785,8 +3754,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3785 | if (portp == (stlport_t *) NULL) | 3754 | if (portp == (stlport_t *) NULL) |
3786 | return; | 3755 | return; |
3787 | 3756 | ||
3788 | save_flags(flags); | 3757 | spin_lock_irqsave(&brd_lock, flags); |
3789 | cli(); | ||
3790 | BRDENABLE(portp->brdnr, portp->pagenr); | 3758 | BRDENABLE(portp->brdnr, portp->pagenr); |
3791 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3792 | stl_cd1400ccrwait(portp); | 3760 | stl_cd1400ccrwait(portp); |
@@ -3794,7 +3762,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3794 | stl_cd1400ccrwait(portp); | 3762 | stl_cd1400ccrwait(portp); |
3795 | portp->tx.tail = portp->tx.head; | 3763 | portp->tx.tail = portp->tx.head; |
3796 | BRDDISABLE(portp->brdnr); | 3764 | BRDDISABLE(portp->brdnr); |
3797 | restore_flags(flags); | 3765 | spin_unlock_irqrestore(&brd_lock, flags); |
3798 | } | 3766 | } |
3799 | 3767 | ||
3800 | /*****************************************************************************/ | 3768 | /*****************************************************************************/ |
@@ -3833,6 +3801,7 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3833 | (int) panelp, iobase); | 3801 | (int) panelp, iobase); |
3834 | #endif | 3802 | #endif |
3835 | 3803 | ||
3804 | spin_lock(&brd_lock); | ||
3836 | outb(SVRR, iobase); | 3805 | outb(SVRR, iobase); |
3837 | svrtype = inb(iobase + EREG_DATA); | 3806 | svrtype = inb(iobase + EREG_DATA); |
3838 | if (panelp->nrports > 4) { | 3807 | if (panelp->nrports > 4) { |
@@ -3846,6 +3815,8 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3846 | stl_cd1400txisr(panelp, iobase); | 3815 | stl_cd1400txisr(panelp, iobase); |
3847 | else if (svrtype & SVRR_MDM) | 3816 | else if (svrtype & SVRR_MDM) |
3848 | stl_cd1400mdmisr(panelp, iobase); | 3817 | stl_cd1400mdmisr(panelp, iobase); |
3818 | |||
3819 | spin_unlock(&brd_lock); | ||
3849 | } | 3820 | } |
3850 | 3821 | ||
3851 | /*****************************************************************************/ | 3822 | /*****************************************************************************/ |
@@ -4433,8 +4404,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4433 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 4404 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
4434 | #endif | 4405 | #endif |
4435 | 4406 | ||
4436 | save_flags(flags); | 4407 | spin_lock_irqsave(&brd_lock, flags); |
4437 | cli(); | ||
4438 | BRDENABLE(portp->brdnr, portp->pagenr); | 4408 | BRDENABLE(portp->brdnr, portp->pagenr); |
4439 | stl_sc26198setreg(portp, IMR, 0); | 4409 | stl_sc26198setreg(portp, IMR, 0); |
4440 | stl_sc26198updatereg(portp, MR0, mr0); | 4410 | stl_sc26198updatereg(portp, MR0, mr0); |
@@ -4461,7 +4431,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4461 | portp->imr = (portp->imr & ~imroff) | imron; | 4431 | portp->imr = (portp->imr & ~imroff) | imron; |
4462 | stl_sc26198setreg(portp, IMR, portp->imr); | 4432 | stl_sc26198setreg(portp, IMR, portp->imr); |
4463 | BRDDISABLE(portp->brdnr); | 4433 | BRDDISABLE(portp->brdnr); |
4464 | restore_flags(flags); | 4434 | spin_unlock_irqrestore(&brd_lock, flags); |
4465 | } | 4435 | } |
4466 | 4436 | ||
4467 | /*****************************************************************************/ | 4437 | /*****************************************************************************/ |
@@ -4491,13 +4461,12 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
4491 | else if (rts > 0) | 4461 | else if (rts > 0) |
4492 | iopioron |= IPR_RTS; | 4462 | iopioron |= IPR_RTS; |
4493 | 4463 | ||
4494 | save_flags(flags); | 4464 | spin_lock_irqsave(&brd_lock, flags); |
4495 | cli(); | ||
4496 | BRDENABLE(portp->brdnr, portp->pagenr); | 4465 | BRDENABLE(portp->brdnr, portp->pagenr); |
4497 | stl_sc26198setreg(portp, IOPIOR, | 4466 | stl_sc26198setreg(portp, IOPIOR, |
4498 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); | 4467 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); |
4499 | BRDDISABLE(portp->brdnr); | 4468 | BRDDISABLE(portp->brdnr); |
4500 | restore_flags(flags); | 4469 | spin_unlock_irqrestore(&brd_lock, flags); |
4501 | } | 4470 | } |
4502 | 4471 | ||
4503 | /*****************************************************************************/ | 4472 | /*****************************************************************************/ |
@@ -4516,12 +4485,11 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
4516 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | 4485 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); |
4517 | #endif | 4486 | #endif |
4518 | 4487 | ||
4519 | save_flags(flags); | 4488 | spin_lock_irqsave(&brd_lock, flags); |
4520 | cli(); | ||
4521 | BRDENABLE(portp->brdnr, portp->pagenr); | 4489 | BRDENABLE(portp->brdnr, portp->pagenr); |
4522 | ipr = stl_sc26198getreg(portp, IPR); | 4490 | ipr = stl_sc26198getreg(portp, IPR); |
4523 | BRDDISABLE(portp->brdnr); | 4491 | BRDDISABLE(portp->brdnr); |
4524 | restore_flags(flags); | 4492 | spin_unlock_irqrestore(&brd_lock, flags); |
4525 | 4493 | ||
4526 | sigs = 0; | 4494 | sigs = 0; |
4527 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; | 4495 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; |
@@ -4558,13 +4526,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
4558 | else if (rx > 0) | 4526 | else if (rx > 0) |
4559 | ccr |= CR_RXENABLE; | 4527 | ccr |= CR_RXENABLE; |
4560 | 4528 | ||
4561 | save_flags(flags); | 4529 | spin_lock_irqsave(&brd_lock, flags); |
4562 | cli(); | ||
4563 | BRDENABLE(portp->brdnr, portp->pagenr); | 4530 | BRDENABLE(portp->brdnr, portp->pagenr); |
4564 | stl_sc26198setreg(portp, SCCR, ccr); | 4531 | stl_sc26198setreg(portp, SCCR, ccr); |
4565 | BRDDISABLE(portp->brdnr); | 4532 | BRDDISABLE(portp->brdnr); |
4566 | portp->crenable = ccr; | 4533 | portp->crenable = ccr; |
4567 | restore_flags(flags); | 4534 | spin_unlock_irqrestore(&brd_lock, flags); |
4568 | } | 4535 | } |
4569 | 4536 | ||
4570 | /*****************************************************************************/ | 4537 | /*****************************************************************************/ |
@@ -4593,15 +4560,14 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
4593 | else if (rx > 0) | 4560 | else if (rx > 0) |
4594 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; | 4561 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; |
4595 | 4562 | ||
4596 | save_flags(flags); | 4563 | spin_lock_irqsave(&brd_lock, flags); |
4597 | cli(); | ||
4598 | BRDENABLE(portp->brdnr, portp->pagenr); | 4564 | BRDENABLE(portp->brdnr, portp->pagenr); |
4599 | stl_sc26198setreg(portp, IMR, imr); | 4565 | stl_sc26198setreg(portp, IMR, imr); |
4600 | BRDDISABLE(portp->brdnr); | 4566 | BRDDISABLE(portp->brdnr); |
4601 | portp->imr = imr; | 4567 | portp->imr = imr; |
4602 | if (tx > 0) | 4568 | if (tx > 0) |
4603 | set_bit(ASYI_TXBUSY, &portp->istate); | 4569 | set_bit(ASYI_TXBUSY, &portp->istate); |
4604 | restore_flags(flags); | 4570 | spin_unlock_irqrestore(&brd_lock, flags); |
4605 | } | 4571 | } |
4606 | 4572 | ||
4607 | /*****************************************************************************/ | 4573 | /*****************************************************************************/ |
@@ -4618,13 +4584,12 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
4618 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | 4584 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); |
4619 | #endif | 4585 | #endif |
4620 | 4586 | ||
4621 | save_flags(flags); | 4587 | spin_lock_irqsave(&brd_lock, flags); |
4622 | cli(); | ||
4623 | BRDENABLE(portp->brdnr, portp->pagenr); | 4588 | BRDENABLE(portp->brdnr, portp->pagenr); |
4624 | portp->imr = 0; | 4589 | portp->imr = 0; |
4625 | stl_sc26198setreg(portp, IMR, 0); | 4590 | stl_sc26198setreg(portp, IMR, 0); |
4626 | BRDDISABLE(portp->brdnr); | 4591 | BRDDISABLE(portp->brdnr); |
4627 | restore_flags(flags); | 4592 | spin_unlock_irqrestore(&brd_lock, flags); |
4628 | } | 4593 | } |
4629 | 4594 | ||
4630 | /*****************************************************************************/ | 4595 | /*****************************************************************************/ |
@@ -4637,8 +4602,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4637 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 4602 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
4638 | #endif | 4603 | #endif |
4639 | 4604 | ||
4640 | save_flags(flags); | 4605 | spin_lock_irqsave(&brd_lock, flags); |
4641 | cli(); | ||
4642 | BRDENABLE(portp->brdnr, portp->pagenr); | 4606 | BRDENABLE(portp->brdnr, portp->pagenr); |
4643 | if (len == 1) { | 4607 | if (len == 1) { |
4644 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4608 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
@@ -4647,7 +4611,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4647 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4611 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
4648 | } | 4612 | } |
4649 | BRDDISABLE(portp->brdnr); | 4613 | BRDDISABLE(portp->brdnr); |
4650 | restore_flags(flags); | 4614 | spin_unlock_irqrestore(&brd_lock, flags); |
4651 | } | 4615 | } |
4652 | 4616 | ||
4653 | /*****************************************************************************/ | 4617 | /*****************************************************************************/ |
@@ -4672,8 +4636,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4672 | if (tty == (struct tty_struct *) NULL) | 4636 | if (tty == (struct tty_struct *) NULL) |
4673 | return; | 4637 | return; |
4674 | 4638 | ||
4675 | save_flags(flags); | 4639 | spin_lock_irqsave(&brd_lock, flags); |
4676 | cli(); | ||
4677 | BRDENABLE(portp->brdnr, portp->pagenr); | 4640 | BRDENABLE(portp->brdnr, portp->pagenr); |
4678 | 4641 | ||
4679 | if (state) { | 4642 | if (state) { |
@@ -4719,7 +4682,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4719 | } | 4682 | } |
4720 | 4683 | ||
4721 | BRDDISABLE(portp->brdnr); | 4684 | BRDDISABLE(portp->brdnr); |
4722 | restore_flags(flags); | 4685 | spin_unlock_irqrestore(&brd_lock, flags); |
4723 | } | 4686 | } |
4724 | 4687 | ||
4725 | /*****************************************************************************/ | 4688 | /*****************************************************************************/ |
@@ -4744,8 +4707,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4744 | if (tty == (struct tty_struct *) NULL) | 4707 | if (tty == (struct tty_struct *) NULL) |
4745 | return; | 4708 | return; |
4746 | 4709 | ||
4747 | save_flags(flags); | 4710 | spin_lock_irqsave(&brd_lock, flags); |
4748 | cli(); | ||
4749 | BRDENABLE(portp->brdnr, portp->pagenr); | 4711 | BRDENABLE(portp->brdnr, portp->pagenr); |
4750 | if (state) { | 4712 | if (state) { |
4751 | mr0 = stl_sc26198getreg(portp, MR0); | 4713 | mr0 = stl_sc26198getreg(portp, MR0); |
@@ -4765,7 +4727,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4765 | stl_sc26198setreg(portp, MR0, mr0); | 4727 | stl_sc26198setreg(portp, MR0, mr0); |
4766 | } | 4728 | } |
4767 | BRDDISABLE(portp->brdnr); | 4729 | BRDDISABLE(portp->brdnr); |
4768 | restore_flags(flags); | 4730 | spin_unlock_irqrestore(&brd_lock, flags); |
4769 | } | 4731 | } |
4770 | 4732 | ||
4771 | /*****************************************************************************/ | 4733 | /*****************************************************************************/ |
@@ -4781,14 +4743,13 @@ static void stl_sc26198flush(stlport_t *portp) | |||
4781 | if (portp == (stlport_t *) NULL) | 4743 | if (portp == (stlport_t *) NULL) |
4782 | return; | 4744 | return; |
4783 | 4745 | ||
4784 | save_flags(flags); | 4746 | spin_lock_irqsave(&brd_lock, flags); |
4785 | cli(); | ||
4786 | BRDENABLE(portp->brdnr, portp->pagenr); | 4747 | BRDENABLE(portp->brdnr, portp->pagenr); |
4787 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); | 4748 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); |
4788 | stl_sc26198setreg(portp, SCCR, portp->crenable); | 4749 | stl_sc26198setreg(portp, SCCR, portp->crenable); |
4789 | BRDDISABLE(portp->brdnr); | 4750 | BRDDISABLE(portp->brdnr); |
4790 | portp->tx.tail = portp->tx.head; | 4751 | portp->tx.tail = portp->tx.head; |
4791 | restore_flags(flags); | 4752 | spin_unlock_irqrestore(&brd_lock, flags); |
4792 | } | 4753 | } |
4793 | 4754 | ||
4794 | /*****************************************************************************/ | 4755 | /*****************************************************************************/ |
@@ -4815,12 +4776,11 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
4815 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4776 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
4816 | return 1; | 4777 | return 1; |
4817 | 4778 | ||
4818 | save_flags(flags); | 4779 | spin_lock_irqsave(&brd_lock, flags); |
4819 | cli(); | ||
4820 | BRDENABLE(portp->brdnr, portp->pagenr); | 4780 | BRDENABLE(portp->brdnr, portp->pagenr); |
4821 | sr = stl_sc26198getreg(portp, SR); | 4781 | sr = stl_sc26198getreg(portp, SR); |
4822 | BRDDISABLE(portp->brdnr); | 4782 | BRDDISABLE(portp->brdnr); |
4823 | restore_flags(flags); | 4783 | spin_unlock_irqrestore(&brd_lock, flags); |
4824 | 4784 | ||
4825 | return (sr & SR_TXEMPTY) ? 0 : 1; | 4785 | return (sr & SR_TXEMPTY) ? 0 : 1; |
4826 | } | 4786 | } |
@@ -4878,6 +4838,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4878 | stlport_t *portp; | 4838 | stlport_t *portp; |
4879 | unsigned int iack; | 4839 | unsigned int iack; |
4880 | 4840 | ||
4841 | spin_lock(&brd_lock); | ||
4842 | |||
4881 | /* | 4843 | /* |
4882 | * Work around bug in sc26198 chip... Cannot have A6 address | 4844 | * Work around bug in sc26198 chip... Cannot have A6 address |
4883 | * line of UART high, else iack will be returned as 0. | 4845 | * line of UART high, else iack will be returned as 0. |
@@ -4893,6 +4855,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4893 | stl_sc26198txisr(portp); | 4855 | stl_sc26198txisr(portp); |
4894 | else | 4856 | else |
4895 | stl_sc26198otherisr(portp, iack); | 4857 | stl_sc26198otherisr(portp, iack); |
4858 | |||
4859 | spin_unlock(&brd_lock); | ||
4896 | } | 4860 | } |
4897 | 4861 | ||
4898 | /*****************************************************************************/ | 4862 | /*****************************************************************************/ |