diff options
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 225 |
1 files changed, 91 insertions, 134 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index a9c5a7230f89..0f7a542d9041 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/smp_lock.h> | 42 | #include <linux/smp_lock.h> |
43 | #include <linux/devfs_fs_kernel.h> | ||
44 | #include <linux/device.h> | 43 | #include <linux/device.h> |
45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
46 | 45 | ||
@@ -141,15 +140,6 @@ static char *stl_drvversion = "5.6.0"; | |||
141 | static struct tty_driver *stl_serial; | 140 | static struct tty_driver *stl_serial; |
142 | 141 | ||
143 | /* | 142 | /* |
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 | 143 | * Define a local default termios struct. All ports will be created |
154 | * 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 |
155 | * at 9600, 8 data bits, 1 stop bit. | 145 | * at 9600, 8 data bits, 1 stop bit. |
@@ -363,6 +353,14 @@ static unsigned char stl_vecmap[] = { | |||
363 | }; | 353 | }; |
364 | 354 | ||
365 | /* | 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 | /* | ||
366 | * 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 |
367 | * the secondary io address space to be activated and deactivated. | 365 | * the secondary io address space to be activated and deactivated. |
368 | * This way all ECH boards can share their secondary io region. | 366 | * This way all ECH boards can share their secondary io region. |
@@ -725,17 +723,7 @@ static struct class *stallion_class; | |||
725 | 723 | ||
726 | static int __init stallion_module_init(void) | 724 | static int __init stallion_module_init(void) |
727 | { | 725 | { |
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(); | 726 | stl_init(); |
737 | restore_flags(flags); | ||
738 | |||
739 | return 0; | 727 | return 0; |
740 | } | 728 | } |
741 | 729 | ||
@@ -746,7 +734,6 @@ static void __exit stallion_module_exit(void) | |||
746 | stlbrd_t *brdp; | 734 | stlbrd_t *brdp; |
747 | stlpanel_t *panelp; | 735 | stlpanel_t *panelp; |
748 | stlport_t *portp; | 736 | stlport_t *portp; |
749 | unsigned long flags; | ||
750 | int i, j, k; | 737 | int i, j, k; |
751 | 738 | ||
752 | #ifdef DEBUG | 739 | #ifdef DEBUG |
@@ -756,9 +743,6 @@ static void __exit stallion_module_exit(void) | |||
756 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | 743 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, |
757 | stl_drvversion); | 744 | stl_drvversion); |
758 | 745 | ||
759 | save_flags(flags); | ||
760 | cli(); | ||
761 | |||
762 | /* | 746 | /* |
763 | * Free up all allocated resources used by the ports. This includes | 747 | * Free up all allocated resources used by the ports. This includes |
764 | * 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 |
@@ -770,21 +754,15 @@ static void __exit stallion_module_exit(void) | |||
770 | if (i) { | 754 | if (i) { |
771 | printk("STALLION: failed to un-register tty driver, " | 755 | printk("STALLION: failed to un-register tty driver, " |
772 | "errno=%d\n", -i); | 756 | "errno=%d\n", -i); |
773 | restore_flags(flags); | ||
774 | return; | 757 | return; |
775 | } | 758 | } |
776 | for (i = 0; i < 4; i++) { | 759 | for (i = 0; i < 4; i++) |
777 | devfs_remove("staliomem/%d", i); | ||
778 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 760 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); |
779 | } | ||
780 | devfs_remove("staliomem"); | ||
781 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | 761 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) |
782 | printk("STALLION: failed to un-register serial memory device, " | 762 | printk("STALLION: failed to un-register serial memory device, " |
783 | "errno=%d\n", -i); | 763 | "errno=%d\n", -i); |
784 | class_destroy(stallion_class); | 764 | class_destroy(stallion_class); |
785 | 765 | ||
786 | kfree(stl_tmpwritebuf); | ||
787 | |||
788 | for (i = 0; (i < stl_nrbrds); i++) { | 766 | for (i = 0; (i < stl_nrbrds); i++) { |
789 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | 767 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) |
790 | continue; | 768 | continue; |
@@ -814,8 +792,6 @@ static void __exit stallion_module_exit(void) | |||
814 | kfree(brdp); | 792 | kfree(brdp); |
815 | stl_brds[i] = (stlbrd_t *) NULL; | 793 | stl_brds[i] = (stlbrd_t *) NULL; |
816 | } | 794 | } |
817 | |||
818 | restore_flags(flags); | ||
819 | } | 795 | } |
820 | 796 | ||
821 | module_init(stallion_module_init); | 797 | module_init(stallion_module_init); |
@@ -948,7 +924,7 @@ static stlbrd_t *stl_allocbrd(void) | |||
948 | 924 | ||
949 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 925 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
950 | if (!brdp) { | 926 | if (!brdp) { |
951 | printk("STALLION: failed to allocate memory (size=%d)\n", | 927 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
952 | sizeof(stlbrd_t)); | 928 | sizeof(stlbrd_t)); |
953 | return NULL; | 929 | return NULL; |
954 | } | 930 | } |
@@ -1066,16 +1042,17 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1066 | rc = 0; | 1042 | rc = 0; |
1067 | doclocal = 0; | 1043 | doclocal = 0; |
1068 | 1044 | ||
1045 | spin_lock_irqsave(&stallion_lock, flags); | ||
1046 | |||
1069 | if (portp->tty->termios->c_cflag & CLOCAL) | 1047 | if (portp->tty->termios->c_cflag & CLOCAL) |
1070 | doclocal++; | 1048 | doclocal++; |
1071 | 1049 | ||
1072 | save_flags(flags); | ||
1073 | cli(); | ||
1074 | portp->openwaitcnt++; | 1050 | portp->openwaitcnt++; |
1075 | if (! tty_hung_up_p(filp)) | 1051 | if (! tty_hung_up_p(filp)) |
1076 | portp->refcount--; | 1052 | portp->refcount--; |
1077 | 1053 | ||
1078 | for (;;) { | 1054 | for (;;) { |
1055 | /* Takes brd_lock internally */ | ||
1079 | stl_setsignals(portp, 1, 1); | 1056 | stl_setsignals(portp, 1, 1); |
1080 | if (tty_hung_up_p(filp) || | 1057 | if (tty_hung_up_p(filp) || |
1081 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { | 1058 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { |
@@ -1093,13 +1070,14 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1093 | rc = -ERESTARTSYS; | 1070 | rc = -ERESTARTSYS; |
1094 | break; | 1071 | break; |
1095 | } | 1072 | } |
1073 | /* FIXME */ | ||
1096 | interruptible_sleep_on(&portp->open_wait); | 1074 | interruptible_sleep_on(&portp->open_wait); |
1097 | } | 1075 | } |
1098 | 1076 | ||
1099 | if (! tty_hung_up_p(filp)) | 1077 | if (! tty_hung_up_p(filp)) |
1100 | portp->refcount++; | 1078 | portp->refcount++; |
1101 | portp->openwaitcnt--; | 1079 | portp->openwaitcnt--; |
1102 | restore_flags(flags); | 1080 | spin_unlock_irqrestore(&stallion_lock, flags); |
1103 | 1081 | ||
1104 | return rc; | 1082 | return rc; |
1105 | } | 1083 | } |
@@ -1119,16 +1097,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1119 | if (portp == (stlport_t *) NULL) | 1097 | if (portp == (stlport_t *) NULL) |
1120 | return; | 1098 | return; |
1121 | 1099 | ||
1122 | save_flags(flags); | 1100 | spin_lock_irqsave(&stallion_lock, flags); |
1123 | cli(); | ||
1124 | if (tty_hung_up_p(filp)) { | 1101 | if (tty_hung_up_p(filp)) { |
1125 | restore_flags(flags); | 1102 | spin_unlock_irqrestore(&stallion_lock, flags); |
1126 | return; | 1103 | return; |
1127 | } | 1104 | } |
1128 | if ((tty->count == 1) && (portp->refcount != 1)) | 1105 | if ((tty->count == 1) && (portp->refcount != 1)) |
1129 | portp->refcount = 1; | 1106 | portp->refcount = 1; |
1130 | if (portp->refcount-- > 1) { | 1107 | if (portp->refcount-- > 1) { |
1131 | restore_flags(flags); | 1108 | spin_unlock_irqrestore(&stallion_lock, flags); |
1132 | return; | 1109 | return; |
1133 | } | 1110 | } |
1134 | 1111 | ||
@@ -1142,11 +1119,18 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1142 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | 1119 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) |
1143 | */ | 1120 | */ |
1144 | tty->closing = 1; | 1121 | tty->closing = 1; |
1122 | |||
1123 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1124 | |||
1145 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1125 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1146 | tty_wait_until_sent(tty, portp->closing_wait); | 1126 | tty_wait_until_sent(tty, portp->closing_wait); |
1147 | stl_waituntilsent(tty, (HZ / 2)); | 1127 | stl_waituntilsent(tty, (HZ / 2)); |
1148 | 1128 | ||
1129 | |||
1130 | spin_lock_irqsave(&stallion_lock, flags); | ||
1149 | portp->flags &= ~ASYNC_INITIALIZED; | 1131 | portp->flags &= ~ASYNC_INITIALIZED; |
1132 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1133 | |||
1150 | stl_disableintrs(portp); | 1134 | stl_disableintrs(portp); |
1151 | if (tty->termios->c_cflag & HUPCL) | 1135 | if (tty->termios->c_cflag & HUPCL) |
1152 | stl_setsignals(portp, 0, 0); | 1136 | stl_setsignals(portp, 0, 0); |
@@ -1173,7 +1157,6 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1173 | 1157 | ||
1174 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1158 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1175 | wake_up_interruptible(&portp->close_wait); | 1159 | wake_up_interruptible(&portp->close_wait); |
1176 | restore_flags(flags); | ||
1177 | } | 1160 | } |
1178 | 1161 | ||
1179 | /*****************************************************************************/ | 1162 | /*****************************************************************************/ |
@@ -1195,9 +1178,6 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1195 | (int) tty, (int) buf, count); | 1178 | (int) tty, (int) buf, count); |
1196 | #endif | 1179 | #endif |
1197 | 1180 | ||
1198 | if ((tty == (struct tty_struct *) NULL) || | ||
1199 | (stl_tmpwritebuf == (char *) NULL)) | ||
1200 | return 0; | ||
1201 | portp = tty->driver_data; | 1181 | portp = tty->driver_data; |
1202 | if (portp == (stlport_t *) NULL) | 1182 | if (portp == (stlport_t *) NULL) |
1203 | return 0; | 1183 | return 0; |
@@ -1302,11 +1282,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1302 | if (portp->tx.buf == (char *) NULL) | 1282 | if (portp->tx.buf == (char *) NULL) |
1303 | return; | 1283 | return; |
1304 | 1284 | ||
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); | 1285 | stl_startrxtx(portp, -1, 1); |
1311 | } | 1286 | } |
1312 | 1287 | ||
@@ -1977,12 +1952,14 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
1977 | unsigned int iobase; | 1952 | unsigned int iobase; |
1978 | int handled = 0; | 1953 | int handled = 0; |
1979 | 1954 | ||
1955 | spin_lock(&brd_lock); | ||
1980 | panelp = brdp->panels[0]; | 1956 | panelp = brdp->panels[0]; |
1981 | iobase = panelp->iobase; | 1957 | iobase = panelp->iobase; |
1982 | while (inb(brdp->iostatus) & EIO_INTRPEND) { | 1958 | while (inb(brdp->iostatus) & EIO_INTRPEND) { |
1983 | handled = 1; | 1959 | handled = 1; |
1984 | (* panelp->isr)(panelp, iobase); | 1960 | (* panelp->isr)(panelp, iobase); |
1985 | } | 1961 | } |
1962 | spin_unlock(&brd_lock); | ||
1986 | return handled; | 1963 | return handled; |
1987 | } | 1964 | } |
1988 | 1965 | ||
@@ -2168,7 +2145,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2168 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 2145 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
2169 | if (!portp) { | 2146 | if (!portp) { |
2170 | printk("STALLION: failed to allocate memory " | 2147 | printk("STALLION: failed to allocate memory " |
2171 | "(size=%d)\n", sizeof(stlport_t)); | 2148 | "(size=%Zd)\n", sizeof(stlport_t)); |
2172 | break; | 2149 | break; |
2173 | } | 2150 | } |
2174 | 2151 | ||
@@ -2304,7 +2281,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2304 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2281 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2305 | if (!panelp) { | 2282 | if (!panelp) { |
2306 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2283 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2307 | "(size=%d)\n", sizeof(stlpanel_t)); | 2284 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2308 | return -ENOMEM; | 2285 | return -ENOMEM; |
2309 | } | 2286 | } |
2310 | 2287 | ||
@@ -2478,7 +2455,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2478 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2455 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2479 | if (!panelp) { | 2456 | if (!panelp) { |
2480 | printk("STALLION: failed to allocate memory " | 2457 | printk("STALLION: failed to allocate memory " |
2481 | "(size=%d)\n", sizeof(stlpanel_t)); | 2458 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2482 | break; | 2459 | break; |
2483 | } | 2460 | } |
2484 | panelp->magic = STL_PANELMAGIC; | 2461 | panelp->magic = STL_PANELMAGIC; |
@@ -2879,8 +2856,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2879 | portp->stats.lflags = 0; | 2856 | portp->stats.lflags = 0; |
2880 | portp->stats.rxbuffered = 0; | 2857 | portp->stats.rxbuffered = 0; |
2881 | 2858 | ||
2882 | save_flags(flags); | 2859 | spin_lock_irqsave(&stallion_lock, flags); |
2883 | cli(); | ||
2884 | if (portp->tty != (struct tty_struct *) NULL) { | 2860 | if (portp->tty != (struct tty_struct *) NULL) { |
2885 | if (portp->tty->driver_data == portp) { | 2861 | if (portp->tty->driver_data == portp) { |
2886 | portp->stats.ttystate = portp->tty->flags; | 2862 | portp->stats.ttystate = portp->tty->flags; |
@@ -2894,7 +2870,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2894 | } | 2870 | } |
2895 | } | 2871 | } |
2896 | } | 2872 | } |
2897 | restore_flags(flags); | 2873 | spin_unlock_irqrestore(&stallion_lock, flags); |
2898 | 2874 | ||
2899 | head = portp->tx.head; | 2875 | head = portp->tx.head; |
2900 | tail = portp->tx.tail; | 2876 | tail = portp->tx.tail; |
@@ -3049,6 +3025,9 @@ static int __init stl_init(void) | |||
3049 | int i; | 3025 | int i; |
3050 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | 3026 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); |
3051 | 3027 | ||
3028 | spin_lock_init(&stallion_lock); | ||
3029 | spin_lock_init(&brd_lock); | ||
3030 | |||
3052 | stl_initbrds(); | 3031 | stl_initbrds(); |
3053 | 3032 | ||
3054 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | 3033 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); |
@@ -3056,35 +3035,21 @@ static int __init stl_init(void) | |||
3056 | return -1; | 3035 | return -1; |
3057 | 3036 | ||
3058 | /* | 3037 | /* |
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 | 3038 | * Set up a character driver for per board stuff. This is mainly used |
3068 | * to do stats ioctls on the ports. | 3039 | * to do stats ioctls on the ports. |
3069 | */ | 3040 | */ |
3070 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) | 3041 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) |
3071 | printk("STALLION: failed to register serial board device\n"); | 3042 | printk("STALLION: failed to register serial board device\n"); |
3072 | devfs_mk_dir("staliomem"); | ||
3073 | 3043 | ||
3074 | stallion_class = class_create(THIS_MODULE, "staliomem"); | 3044 | stallion_class = class_create(THIS_MODULE, "staliomem"); |
3075 | for (i = 0; i < 4; i++) { | 3045 | for (i = 0; i < 4; i++) |
3076 | devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), | ||
3077 | S_IFCHR|S_IRUSR|S_IWUSR, | ||
3078 | "staliomem/%d", i); | ||
3079 | class_device_create(stallion_class, NULL, | 3046 | class_device_create(stallion_class, NULL, |
3080 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | 3047 | MKDEV(STL_SIOMEMMAJOR, i), NULL, |
3081 | "staliomem%d", i); | 3048 | "staliomem%d", i); |
3082 | } | ||
3083 | 3049 | ||
3084 | stl_serial->owner = THIS_MODULE; | 3050 | stl_serial->owner = THIS_MODULE; |
3085 | stl_serial->driver_name = stl_drvname; | 3051 | stl_serial->driver_name = stl_drvname; |
3086 | stl_serial->name = "ttyE"; | 3052 | stl_serial->name = "ttyE"; |
3087 | stl_serial->devfs_name = "tts/E"; | ||
3088 | stl_serial->major = STL_SERIALMAJOR; | 3053 | stl_serial->major = STL_SERIALMAJOR; |
3089 | stl_serial->minor_start = 0; | 3054 | stl_serial->minor_start = 0; |
3090 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | 3055 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; |
@@ -3147,11 +3112,13 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3147 | unsigned int gfrcr; | 3112 | unsigned int gfrcr; |
3148 | int chipmask, i, j; | 3113 | int chipmask, i, j; |
3149 | int nrchips, uartaddr, ioaddr; | 3114 | int nrchips, uartaddr, ioaddr; |
3115 | unsigned long flags; | ||
3150 | 3116 | ||
3151 | #ifdef DEBUG | 3117 | #ifdef DEBUG |
3152 | 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); |
3153 | #endif | 3119 | #endif |
3154 | 3120 | ||
3121 | spin_lock_irqsave(&brd_lock, flags); | ||
3155 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3122 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
3156 | 3123 | ||
3157 | /* | 3124 | /* |
@@ -3189,6 +3156,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3189 | } | 3156 | } |
3190 | 3157 | ||
3191 | BRDDISABLE(panelp->brdnr); | 3158 | BRDDISABLE(panelp->brdnr); |
3159 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3192 | return chipmask; | 3160 | return chipmask; |
3193 | } | 3161 | } |
3194 | 3162 | ||
@@ -3200,6 +3168,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3200 | 3168 | ||
3201 | 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) |
3202 | { | 3170 | { |
3171 | unsigned long flags; | ||
3203 | #ifdef DEBUG | 3172 | #ifdef DEBUG |
3204 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3173 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", |
3205 | (int) brdp, (int) panelp, (int) portp); | 3174 | (int) brdp, (int) panelp, (int) portp); |
@@ -3209,6 +3178,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3209 | (portp == (stlport_t *) NULL)) | 3178 | (portp == (stlport_t *) NULL)) |
3210 | return; | 3179 | return; |
3211 | 3180 | ||
3181 | spin_lock_irqsave(&brd_lock, flags); | ||
3212 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || | 3182 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || |
3213 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); | 3183 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); |
3214 | portp->uartaddr = (portp->portnr & 0x04) << 5; | 3184 | portp->uartaddr = (portp->portnr & 0x04) << 5; |
@@ -3219,6 +3189,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3219 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); | 3189 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); |
3220 | portp->hwid = stl_cd1400getreg(portp, GFRCR); | 3190 | portp->hwid = stl_cd1400getreg(portp, GFRCR); |
3221 | BRDDISABLE(portp->brdnr); | 3191 | BRDDISABLE(portp->brdnr); |
3192 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3222 | } | 3193 | } |
3223 | 3194 | ||
3224 | /*****************************************************************************/ | 3195 | /*****************************************************************************/ |
@@ -3428,8 +3399,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3428 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3399 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
3429 | #endif | 3400 | #endif |
3430 | 3401 | ||
3431 | save_flags(flags); | 3402 | spin_lock_irqsave(&brd_lock, flags); |
3432 | cli(); | ||
3433 | BRDENABLE(portp->brdnr, portp->pagenr); | 3403 | BRDENABLE(portp->brdnr, portp->pagenr); |
3434 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); | 3404 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); |
3435 | srer = stl_cd1400getreg(portp, SRER); | 3405 | srer = stl_cd1400getreg(portp, SRER); |
@@ -3466,7 +3436,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3466 | portp->sigs &= ~TIOCM_CD; | 3436 | portp->sigs &= ~TIOCM_CD; |
3467 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); | 3437 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); |
3468 | BRDDISABLE(portp->brdnr); | 3438 | BRDDISABLE(portp->brdnr); |
3469 | restore_flags(flags); | 3439 | spin_unlock_irqrestore(&brd_lock, flags); |
3470 | } | 3440 | } |
3471 | 3441 | ||
3472 | /*****************************************************************************/ | 3442 | /*****************************************************************************/ |
@@ -3492,8 +3462,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3492 | if (rts > 0) | 3462 | if (rts > 0) |
3493 | msvr2 = MSVR2_RTS; | 3463 | msvr2 = MSVR2_RTS; |
3494 | 3464 | ||
3495 | save_flags(flags); | 3465 | spin_lock_irqsave(&brd_lock, flags); |
3496 | cli(); | ||
3497 | BRDENABLE(portp->brdnr, portp->pagenr); | 3466 | BRDENABLE(portp->brdnr, portp->pagenr); |
3498 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3467 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3499 | if (rts >= 0) | 3468 | if (rts >= 0) |
@@ -3501,7 +3470,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3501 | if (dtr >= 0) | 3470 | if (dtr >= 0) |
3502 | stl_cd1400setreg(portp, MSVR1, msvr1); | 3471 | stl_cd1400setreg(portp, MSVR1, msvr1); |
3503 | BRDDISABLE(portp->brdnr); | 3472 | BRDDISABLE(portp->brdnr); |
3504 | restore_flags(flags); | 3473 | spin_unlock_irqrestore(&brd_lock, flags); |
3505 | } | 3474 | } |
3506 | 3475 | ||
3507 | /*****************************************************************************/ | 3476 | /*****************************************************************************/ |
@@ -3520,14 +3489,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
3520 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | 3489 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); |
3521 | #endif | 3490 | #endif |
3522 | 3491 | ||
3523 | save_flags(flags); | 3492 | spin_lock_irqsave(&brd_lock, flags); |
3524 | cli(); | ||
3525 | BRDENABLE(portp->brdnr, portp->pagenr); | 3493 | BRDENABLE(portp->brdnr, portp->pagenr); |
3526 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3494 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3527 | msvr1 = stl_cd1400getreg(portp, MSVR1); | 3495 | msvr1 = stl_cd1400getreg(portp, MSVR1); |
3528 | msvr2 = stl_cd1400getreg(portp, MSVR2); | 3496 | msvr2 = stl_cd1400getreg(portp, MSVR2); |
3529 | BRDDISABLE(portp->brdnr); | 3497 | BRDDISABLE(portp->brdnr); |
3530 | restore_flags(flags); | 3498 | spin_unlock_irqrestore(&brd_lock, flags); |
3531 | 3499 | ||
3532 | sigs = 0; | 3500 | sigs = 0; |
3533 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; | 3501 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; |
@@ -3569,15 +3537,14 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
3569 | else if (rx > 0) | 3537 | else if (rx > 0) |
3570 | ccr |= CCR_RXENABLE; | 3538 | ccr |= CCR_RXENABLE; |
3571 | 3539 | ||
3572 | save_flags(flags); | 3540 | spin_lock_irqsave(&brd_lock, flags); |
3573 | cli(); | ||
3574 | BRDENABLE(portp->brdnr, portp->pagenr); | 3541 | BRDENABLE(portp->brdnr, portp->pagenr); |
3575 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3542 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3576 | stl_cd1400ccrwait(portp); | 3543 | stl_cd1400ccrwait(portp); |
3577 | stl_cd1400setreg(portp, CCR, ccr); | 3544 | stl_cd1400setreg(portp, CCR, ccr); |
3578 | stl_cd1400ccrwait(portp); | 3545 | stl_cd1400ccrwait(portp); |
3579 | BRDDISABLE(portp->brdnr); | 3546 | BRDDISABLE(portp->brdnr); |
3580 | restore_flags(flags); | 3547 | spin_unlock_irqrestore(&brd_lock, flags); |
3581 | } | 3548 | } |
3582 | 3549 | ||
3583 | /*****************************************************************************/ | 3550 | /*****************************************************************************/ |
@@ -3609,8 +3576,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3609 | else if (rx > 0) | 3576 | else if (rx > 0) |
3610 | sreron |= SRER_RXDATA; | 3577 | sreron |= SRER_RXDATA; |
3611 | 3578 | ||
3612 | save_flags(flags); | 3579 | spin_lock_irqsave(&brd_lock, flags); |
3613 | cli(); | ||
3614 | BRDENABLE(portp->brdnr, portp->pagenr); | 3580 | BRDENABLE(portp->brdnr, portp->pagenr); |
3615 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3581 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3616 | stl_cd1400setreg(portp, SRER, | 3582 | stl_cd1400setreg(portp, SRER, |
@@ -3618,7 +3584,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3618 | BRDDISABLE(portp->brdnr); | 3584 | BRDDISABLE(portp->brdnr); |
3619 | if (tx > 0) | 3585 | if (tx > 0) |
3620 | set_bit(ASYI_TXBUSY, &portp->istate); | 3586 | set_bit(ASYI_TXBUSY, &portp->istate); |
3621 | restore_flags(flags); | 3587 | spin_unlock_irqrestore(&brd_lock, flags); |
3622 | } | 3588 | } |
3623 | 3589 | ||
3624 | /*****************************************************************************/ | 3590 | /*****************************************************************************/ |
@@ -3634,13 +3600,12 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
3634 | #ifdef DEBUG | 3600 | #ifdef DEBUG |
3635 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3601 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); |
3636 | #endif | 3602 | #endif |
3637 | save_flags(flags); | 3603 | spin_lock_irqsave(&brd_lock, flags); |
3638 | cli(); | ||
3639 | BRDENABLE(portp->brdnr, portp->pagenr); | 3604 | BRDENABLE(portp->brdnr, portp->pagenr); |
3640 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3605 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3641 | stl_cd1400setreg(portp, SRER, 0); | 3606 | stl_cd1400setreg(portp, SRER, 0); |
3642 | BRDDISABLE(portp->brdnr); | 3607 | BRDDISABLE(portp->brdnr); |
3643 | restore_flags(flags); | 3608 | spin_unlock_irqrestore(&brd_lock, flags); |
3644 | } | 3609 | } |
3645 | 3610 | ||
3646 | /*****************************************************************************/ | 3611 | /*****************************************************************************/ |
@@ -3653,8 +3618,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3653 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 3618 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
3654 | #endif | 3619 | #endif |
3655 | 3620 | ||
3656 | save_flags(flags); | 3621 | spin_lock_irqsave(&brd_lock, flags); |
3657 | cli(); | ||
3658 | BRDENABLE(portp->brdnr, portp->pagenr); | 3622 | BRDENABLE(portp->brdnr, portp->pagenr); |
3659 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3623 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3660 | stl_cd1400setreg(portp, SRER, | 3624 | stl_cd1400setreg(portp, SRER, |
@@ -3664,7 +3628,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3664 | portp->brklen = len; | 3628 | portp->brklen = len; |
3665 | if (len == 1) | 3629 | if (len == 1) |
3666 | portp->stats.txbreaks++; | 3630 | portp->stats.txbreaks++; |
3667 | restore_flags(flags); | 3631 | spin_unlock_irqrestore(&brd_lock, flags); |
3668 | } | 3632 | } |
3669 | 3633 | ||
3670 | /*****************************************************************************/ | 3634 | /*****************************************************************************/ |
@@ -3688,8 +3652,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3688 | if (tty == (struct tty_struct *) NULL) | 3652 | if (tty == (struct tty_struct *) NULL) |
3689 | return; | 3653 | return; |
3690 | 3654 | ||
3691 | save_flags(flags); | 3655 | spin_lock_irqsave(&brd_lock, flags); |
3692 | cli(); | ||
3693 | BRDENABLE(portp->brdnr, portp->pagenr); | 3656 | BRDENABLE(portp->brdnr, portp->pagenr); |
3694 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3657 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3695 | 3658 | ||
@@ -3729,7 +3692,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3729 | } | 3692 | } |
3730 | 3693 | ||
3731 | BRDDISABLE(portp->brdnr); | 3694 | BRDDISABLE(portp->brdnr); |
3732 | restore_flags(flags); | 3695 | spin_unlock_irqrestore(&brd_lock, flags); |
3733 | } | 3696 | } |
3734 | 3697 | ||
3735 | /*****************************************************************************/ | 3698 | /*****************************************************************************/ |
@@ -3753,8 +3716,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3753 | if (tty == (struct tty_struct *) NULL) | 3716 | if (tty == (struct tty_struct *) NULL) |
3754 | return; | 3717 | return; |
3755 | 3718 | ||
3756 | save_flags(flags); | 3719 | spin_lock_irqsave(&brd_lock, flags); |
3757 | cli(); | ||
3758 | BRDENABLE(portp->brdnr, portp->pagenr); | 3720 | BRDENABLE(portp->brdnr, portp->pagenr); |
3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3721 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3760 | if (state) { | 3722 | if (state) { |
@@ -3769,7 +3731,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3769 | stl_cd1400ccrwait(portp); | 3731 | stl_cd1400ccrwait(portp); |
3770 | } | 3732 | } |
3771 | BRDDISABLE(portp->brdnr); | 3733 | BRDDISABLE(portp->brdnr); |
3772 | restore_flags(flags); | 3734 | spin_unlock_irqrestore(&brd_lock, flags); |
3773 | } | 3735 | } |
3774 | 3736 | ||
3775 | /*****************************************************************************/ | 3737 | /*****************************************************************************/ |
@@ -3785,8 +3747,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3785 | if (portp == (stlport_t *) NULL) | 3747 | if (portp == (stlport_t *) NULL) |
3786 | return; | 3748 | return; |
3787 | 3749 | ||
3788 | save_flags(flags); | 3750 | spin_lock_irqsave(&brd_lock, flags); |
3789 | cli(); | ||
3790 | BRDENABLE(portp->brdnr, portp->pagenr); | 3751 | BRDENABLE(portp->brdnr, portp->pagenr); |
3791 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3752 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3792 | stl_cd1400ccrwait(portp); | 3753 | stl_cd1400ccrwait(portp); |
@@ -3794,7 +3755,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3794 | stl_cd1400ccrwait(portp); | 3755 | stl_cd1400ccrwait(portp); |
3795 | portp->tx.tail = portp->tx.head; | 3756 | portp->tx.tail = portp->tx.head; |
3796 | BRDDISABLE(portp->brdnr); | 3757 | BRDDISABLE(portp->brdnr); |
3797 | restore_flags(flags); | 3758 | spin_unlock_irqrestore(&brd_lock, flags); |
3798 | } | 3759 | } |
3799 | 3760 | ||
3800 | /*****************************************************************************/ | 3761 | /*****************************************************************************/ |
@@ -3833,6 +3794,7 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3833 | (int) panelp, iobase); | 3794 | (int) panelp, iobase); |
3834 | #endif | 3795 | #endif |
3835 | 3796 | ||
3797 | spin_lock(&brd_lock); | ||
3836 | outb(SVRR, iobase); | 3798 | outb(SVRR, iobase); |
3837 | svrtype = inb(iobase + EREG_DATA); | 3799 | svrtype = inb(iobase + EREG_DATA); |
3838 | if (panelp->nrports > 4) { | 3800 | if (panelp->nrports > 4) { |
@@ -3846,6 +3808,8 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3846 | stl_cd1400txisr(panelp, iobase); | 3808 | stl_cd1400txisr(panelp, iobase); |
3847 | else if (svrtype & SVRR_MDM) | 3809 | else if (svrtype & SVRR_MDM) |
3848 | stl_cd1400mdmisr(panelp, iobase); | 3810 | stl_cd1400mdmisr(panelp, iobase); |
3811 | |||
3812 | spin_unlock(&brd_lock); | ||
3849 | } | 3813 | } |
3850 | 3814 | ||
3851 | /*****************************************************************************/ | 3815 | /*****************************************************************************/ |
@@ -4433,8 +4397,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4433 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 4397 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
4434 | #endif | 4398 | #endif |
4435 | 4399 | ||
4436 | save_flags(flags); | 4400 | spin_lock_irqsave(&brd_lock, flags); |
4437 | cli(); | ||
4438 | BRDENABLE(portp->brdnr, portp->pagenr); | 4401 | BRDENABLE(portp->brdnr, portp->pagenr); |
4439 | stl_sc26198setreg(portp, IMR, 0); | 4402 | stl_sc26198setreg(portp, IMR, 0); |
4440 | stl_sc26198updatereg(portp, MR0, mr0); | 4403 | stl_sc26198updatereg(portp, MR0, mr0); |
@@ -4461,7 +4424,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4461 | portp->imr = (portp->imr & ~imroff) | imron; | 4424 | portp->imr = (portp->imr & ~imroff) | imron; |
4462 | stl_sc26198setreg(portp, IMR, portp->imr); | 4425 | stl_sc26198setreg(portp, IMR, portp->imr); |
4463 | BRDDISABLE(portp->brdnr); | 4426 | BRDDISABLE(portp->brdnr); |
4464 | restore_flags(flags); | 4427 | spin_unlock_irqrestore(&brd_lock, flags); |
4465 | } | 4428 | } |
4466 | 4429 | ||
4467 | /*****************************************************************************/ | 4430 | /*****************************************************************************/ |
@@ -4491,13 +4454,12 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
4491 | else if (rts > 0) | 4454 | else if (rts > 0) |
4492 | iopioron |= IPR_RTS; | 4455 | iopioron |= IPR_RTS; |
4493 | 4456 | ||
4494 | save_flags(flags); | 4457 | spin_lock_irqsave(&brd_lock, flags); |
4495 | cli(); | ||
4496 | BRDENABLE(portp->brdnr, portp->pagenr); | 4458 | BRDENABLE(portp->brdnr, portp->pagenr); |
4497 | stl_sc26198setreg(portp, IOPIOR, | 4459 | stl_sc26198setreg(portp, IOPIOR, |
4498 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); | 4460 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); |
4499 | BRDDISABLE(portp->brdnr); | 4461 | BRDDISABLE(portp->brdnr); |
4500 | restore_flags(flags); | 4462 | spin_unlock_irqrestore(&brd_lock, flags); |
4501 | } | 4463 | } |
4502 | 4464 | ||
4503 | /*****************************************************************************/ | 4465 | /*****************************************************************************/ |
@@ -4516,12 +4478,11 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
4516 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | 4478 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); |
4517 | #endif | 4479 | #endif |
4518 | 4480 | ||
4519 | save_flags(flags); | 4481 | spin_lock_irqsave(&brd_lock, flags); |
4520 | cli(); | ||
4521 | BRDENABLE(portp->brdnr, portp->pagenr); | 4482 | BRDENABLE(portp->brdnr, portp->pagenr); |
4522 | ipr = stl_sc26198getreg(portp, IPR); | 4483 | ipr = stl_sc26198getreg(portp, IPR); |
4523 | BRDDISABLE(portp->brdnr); | 4484 | BRDDISABLE(portp->brdnr); |
4524 | restore_flags(flags); | 4485 | spin_unlock_irqrestore(&brd_lock, flags); |
4525 | 4486 | ||
4526 | sigs = 0; | 4487 | sigs = 0; |
4527 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; | 4488 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; |
@@ -4558,13 +4519,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
4558 | else if (rx > 0) | 4519 | else if (rx > 0) |
4559 | ccr |= CR_RXENABLE; | 4520 | ccr |= CR_RXENABLE; |
4560 | 4521 | ||
4561 | save_flags(flags); | 4522 | spin_lock_irqsave(&brd_lock, flags); |
4562 | cli(); | ||
4563 | BRDENABLE(portp->brdnr, portp->pagenr); | 4523 | BRDENABLE(portp->brdnr, portp->pagenr); |
4564 | stl_sc26198setreg(portp, SCCR, ccr); | 4524 | stl_sc26198setreg(portp, SCCR, ccr); |
4565 | BRDDISABLE(portp->brdnr); | 4525 | BRDDISABLE(portp->brdnr); |
4566 | portp->crenable = ccr; | 4526 | portp->crenable = ccr; |
4567 | restore_flags(flags); | 4527 | spin_unlock_irqrestore(&brd_lock, flags); |
4568 | } | 4528 | } |
4569 | 4529 | ||
4570 | /*****************************************************************************/ | 4530 | /*****************************************************************************/ |
@@ -4593,15 +4553,14 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
4593 | else if (rx > 0) | 4553 | else if (rx > 0) |
4594 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; | 4554 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; |
4595 | 4555 | ||
4596 | save_flags(flags); | 4556 | spin_lock_irqsave(&brd_lock, flags); |
4597 | cli(); | ||
4598 | BRDENABLE(portp->brdnr, portp->pagenr); | 4557 | BRDENABLE(portp->brdnr, portp->pagenr); |
4599 | stl_sc26198setreg(portp, IMR, imr); | 4558 | stl_sc26198setreg(portp, IMR, imr); |
4600 | BRDDISABLE(portp->brdnr); | 4559 | BRDDISABLE(portp->brdnr); |
4601 | portp->imr = imr; | 4560 | portp->imr = imr; |
4602 | if (tx > 0) | 4561 | if (tx > 0) |
4603 | set_bit(ASYI_TXBUSY, &portp->istate); | 4562 | set_bit(ASYI_TXBUSY, &portp->istate); |
4604 | restore_flags(flags); | 4563 | spin_unlock_irqrestore(&brd_lock, flags); |
4605 | } | 4564 | } |
4606 | 4565 | ||
4607 | /*****************************************************************************/ | 4566 | /*****************************************************************************/ |
@@ -4618,13 +4577,12 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
4618 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | 4577 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); |
4619 | #endif | 4578 | #endif |
4620 | 4579 | ||
4621 | save_flags(flags); | 4580 | spin_lock_irqsave(&brd_lock, flags); |
4622 | cli(); | ||
4623 | BRDENABLE(portp->brdnr, portp->pagenr); | 4581 | BRDENABLE(portp->brdnr, portp->pagenr); |
4624 | portp->imr = 0; | 4582 | portp->imr = 0; |
4625 | stl_sc26198setreg(portp, IMR, 0); | 4583 | stl_sc26198setreg(portp, IMR, 0); |
4626 | BRDDISABLE(portp->brdnr); | 4584 | BRDDISABLE(portp->brdnr); |
4627 | restore_flags(flags); | 4585 | spin_unlock_irqrestore(&brd_lock, flags); |
4628 | } | 4586 | } |
4629 | 4587 | ||
4630 | /*****************************************************************************/ | 4588 | /*****************************************************************************/ |
@@ -4637,8 +4595,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4637 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 4595 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
4638 | #endif | 4596 | #endif |
4639 | 4597 | ||
4640 | save_flags(flags); | 4598 | spin_lock_irqsave(&brd_lock, flags); |
4641 | cli(); | ||
4642 | BRDENABLE(portp->brdnr, portp->pagenr); | 4599 | BRDENABLE(portp->brdnr, portp->pagenr); |
4643 | if (len == 1) { | 4600 | if (len == 1) { |
4644 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4601 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
@@ -4647,7 +4604,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4647 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4604 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
4648 | } | 4605 | } |
4649 | BRDDISABLE(portp->brdnr); | 4606 | BRDDISABLE(portp->brdnr); |
4650 | restore_flags(flags); | 4607 | spin_unlock_irqrestore(&brd_lock, flags); |
4651 | } | 4608 | } |
4652 | 4609 | ||
4653 | /*****************************************************************************/ | 4610 | /*****************************************************************************/ |
@@ -4672,8 +4629,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4672 | if (tty == (struct tty_struct *) NULL) | 4629 | if (tty == (struct tty_struct *) NULL) |
4673 | return; | 4630 | return; |
4674 | 4631 | ||
4675 | save_flags(flags); | 4632 | spin_lock_irqsave(&brd_lock, flags); |
4676 | cli(); | ||
4677 | BRDENABLE(portp->brdnr, portp->pagenr); | 4633 | BRDENABLE(portp->brdnr, portp->pagenr); |
4678 | 4634 | ||
4679 | if (state) { | 4635 | if (state) { |
@@ -4719,7 +4675,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4719 | } | 4675 | } |
4720 | 4676 | ||
4721 | BRDDISABLE(portp->brdnr); | 4677 | BRDDISABLE(portp->brdnr); |
4722 | restore_flags(flags); | 4678 | spin_unlock_irqrestore(&brd_lock, flags); |
4723 | } | 4679 | } |
4724 | 4680 | ||
4725 | /*****************************************************************************/ | 4681 | /*****************************************************************************/ |
@@ -4744,8 +4700,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4744 | if (tty == (struct tty_struct *) NULL) | 4700 | if (tty == (struct tty_struct *) NULL) |
4745 | return; | 4701 | return; |
4746 | 4702 | ||
4747 | save_flags(flags); | 4703 | spin_lock_irqsave(&brd_lock, flags); |
4748 | cli(); | ||
4749 | BRDENABLE(portp->brdnr, portp->pagenr); | 4704 | BRDENABLE(portp->brdnr, portp->pagenr); |
4750 | if (state) { | 4705 | if (state) { |
4751 | mr0 = stl_sc26198getreg(portp, MR0); | 4706 | mr0 = stl_sc26198getreg(portp, MR0); |
@@ -4765,7 +4720,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4765 | stl_sc26198setreg(portp, MR0, mr0); | 4720 | stl_sc26198setreg(portp, MR0, mr0); |
4766 | } | 4721 | } |
4767 | BRDDISABLE(portp->brdnr); | 4722 | BRDDISABLE(portp->brdnr); |
4768 | restore_flags(flags); | 4723 | spin_unlock_irqrestore(&brd_lock, flags); |
4769 | } | 4724 | } |
4770 | 4725 | ||
4771 | /*****************************************************************************/ | 4726 | /*****************************************************************************/ |
@@ -4781,14 +4736,13 @@ static void stl_sc26198flush(stlport_t *portp) | |||
4781 | if (portp == (stlport_t *) NULL) | 4736 | if (portp == (stlport_t *) NULL) |
4782 | return; | 4737 | return; |
4783 | 4738 | ||
4784 | save_flags(flags); | 4739 | spin_lock_irqsave(&brd_lock, flags); |
4785 | cli(); | ||
4786 | BRDENABLE(portp->brdnr, portp->pagenr); | 4740 | BRDENABLE(portp->brdnr, portp->pagenr); |
4787 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); | 4741 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); |
4788 | stl_sc26198setreg(portp, SCCR, portp->crenable); | 4742 | stl_sc26198setreg(portp, SCCR, portp->crenable); |
4789 | BRDDISABLE(portp->brdnr); | 4743 | BRDDISABLE(portp->brdnr); |
4790 | portp->tx.tail = portp->tx.head; | 4744 | portp->tx.tail = portp->tx.head; |
4791 | restore_flags(flags); | 4745 | spin_unlock_irqrestore(&brd_lock, flags); |
4792 | } | 4746 | } |
4793 | 4747 | ||
4794 | /*****************************************************************************/ | 4748 | /*****************************************************************************/ |
@@ -4815,12 +4769,11 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
4815 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4769 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
4816 | return 1; | 4770 | return 1; |
4817 | 4771 | ||
4818 | save_flags(flags); | 4772 | spin_lock_irqsave(&brd_lock, flags); |
4819 | cli(); | ||
4820 | BRDENABLE(portp->brdnr, portp->pagenr); | 4773 | BRDENABLE(portp->brdnr, portp->pagenr); |
4821 | sr = stl_sc26198getreg(portp, SR); | 4774 | sr = stl_sc26198getreg(portp, SR); |
4822 | BRDDISABLE(portp->brdnr); | 4775 | BRDDISABLE(portp->brdnr); |
4823 | restore_flags(flags); | 4776 | spin_unlock_irqrestore(&brd_lock, flags); |
4824 | 4777 | ||
4825 | return (sr & SR_TXEMPTY) ? 0 : 1; | 4778 | return (sr & SR_TXEMPTY) ? 0 : 1; |
4826 | } | 4779 | } |
@@ -4878,6 +4831,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4878 | stlport_t *portp; | 4831 | stlport_t *portp; |
4879 | unsigned int iack; | 4832 | unsigned int iack; |
4880 | 4833 | ||
4834 | spin_lock(&brd_lock); | ||
4835 | |||
4881 | /* | 4836 | /* |
4882 | * Work around bug in sc26198 chip... Cannot have A6 address | 4837 | * Work around bug in sc26198 chip... Cannot have A6 address |
4883 | * line of UART high, else iack will be returned as 0. | 4838 | * line of UART high, else iack will be returned as 0. |
@@ -4893,6 +4848,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4893 | stl_sc26198txisr(portp); | 4848 | stl_sc26198txisr(portp); |
4894 | else | 4849 | else |
4895 | stl_sc26198otherisr(portp, iack); | 4850 | stl_sc26198otherisr(portp, iack); |
4851 | |||
4852 | spin_unlock(&brd_lock); | ||
4896 | } | 4853 | } |
4897 | 4854 | ||
4898 | /*****************************************************************************/ | 4855 | /*****************************************************************************/ |