aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-03-28 21:24:50 -0500
committerPaul Mackerras <paulus@samba.org>2006-03-28 21:24:50 -0500
commitbac30d1a78d0f11c613968fc8b351a91ed465386 (patch)
treee52f3c876522a2f6047a6ec1c27df2e8a79486b8 /drivers/char
parente8222502ee6157e2713da9e0792c21f4ad458d50 (diff)
parentca9ba4471c1203bb6e759b76e83167fec54fe590 (diff)
Merge ../linux-2.6
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/agp/nvidia-agp.c3
-rw-r--r--drivers/char/drm/drm_fops.c2
-rw-r--r--drivers/char/drm/i810_dma.c2
-rw-r--r--drivers/char/drm/i830_dma.c2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c4
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c7
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c6
-rw-r--r--drivers/char/mem.c2
-rw-r--r--drivers/char/misc.c2
-rw-r--r--drivers/char/mxser.h2
-rw-r--r--drivers/char/synclink.c33
-rw-r--r--drivers/char/synclink_gt.c250
13 files changed, 263 insertions, 54 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7a85b3a26ff8..889cad07774e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -713,7 +713,7 @@ config NVRAM
713 713
714config RTC 714config RTC
715 tristate "Enhanced Real Time Clock Support" 715 tristate "Enhanced Real Time Clock Support"
716 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV 716 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM
717 ---help--- 717 ---help---
718 If you say Y here and create a character special file /dev/rtc with 718 If you say Y here and create a character special file /dev/rtc with
719 major number 10 and minor number 135 using mknod ("man mknod"), you 719 major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 70b8ed9cd172..4c67135c12d8 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -11,6 +11,7 @@
11#include <linux/gfp.h> 11#include <linux/gfp.h>
12#include <linux/page-flags.h> 12#include <linux/page-flags.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/jiffies.h>
14#include "agp.h" 15#include "agp.h"
15 16
16/* NVIDIA registers */ 17/* NVIDIA registers */
@@ -256,7 +257,7 @@ static void nvidia_tlbflush(struct agp_memory *mem)
256 do { 257 do {
257 pci_read_config_dword(nvidia_private.dev_1, 258 pci_read_config_dword(nvidia_private.dev_1,
258 NVIDIA_1_WBC, &wbc_reg); 259 NVIDIA_1_WBC, &wbc_reg);
259 if ((signed)(end - jiffies) <= 0) { 260 if (time_before_eq(end, jiffies)) {
260 printk(KERN_ERR PFX 261 printk(KERN_ERR PFX
261 "TLB flush took more than 3 seconds.\n"); 262 "TLB flush took more than 3 seconds.\n");
262 } 263 }
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 641f7633878c..b7f7951c4587 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -175,7 +175,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
175 drm_device_t *dev = NULL; 175 drm_device_t *dev = NULL;
176 int minor = iminor(inode); 176 int minor = iminor(inode);
177 int err = -ENODEV; 177 int err = -ENODEV;
178 struct file_operations *old_fops; 178 const struct file_operations *old_fops;
179 179
180 DRM_DEBUG("\n"); 180 DRM_DEBUG("\n");
181 181
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index ae0aa6d7e0bb..c658dde3633b 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -126,7 +126,7 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
126 drm_device_t *dev = priv->head->dev; 126 drm_device_t *dev = priv->head->dev;
127 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 127 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
128 drm_i810_private_t *dev_priv = dev->dev_private; 128 drm_i810_private_t *dev_priv = dev->dev_private;
129 struct file_operations *old_fops; 129 const struct file_operations *old_fops;
130 int retcode = 0; 130 int retcode = 0;
131 131
132 if (buf_priv->currently_mapped == I810_BUF_MAPPED) 132 if (buf_priv->currently_mapped == I810_BUF_MAPPED)
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 163f2cbfe60d..b0f815d8cea8 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -128,7 +128,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp)
128 drm_device_t *dev = priv->head->dev; 128 drm_device_t *dev = priv->head->dev;
129 drm_i830_buf_priv_t *buf_priv = buf->dev_private; 129 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
130 drm_i830_private_t *dev_priv = dev->dev_private; 130 drm_i830_private_t *dev_priv = dev->dev_private;
131 struct file_operations *old_fops; 131 const struct file_operations *old_fops;
132 unsigned long virtual; 132 unsigned long virtual;
133 int retcode = 0; 133 int retcode = 0;
134 134
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index b8fb87c6c29f..40eb005b9d77 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -3744,7 +3744,7 @@ static int ipmi_init_msghandler(void)
3744 ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; 3744 ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
3745 add_timer(&ipmi_timer); 3745 add_timer(&ipmi_timer);
3746 3746
3747 notifier_chain_register(&panic_notifier_list, &panic_block); 3747 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
3748 3748
3749 initialized = 1; 3749 initialized = 1;
3750 3750
@@ -3764,7 +3764,7 @@ static __exit void cleanup_ipmi(void)
3764 if (!initialized) 3764 if (!initialized)
3765 return; 3765 return;
3766 3766
3767 notifier_chain_unregister(&panic_notifier_list, &panic_block); 3767 atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block);
3768 3768
3769 /* This can't be called if any interfaces exist, so no worry about 3769 /* This can't be called if any interfaces exist, so no worry about
3770 shutting down the interfaces. */ 3770 shutting down the interfaces. */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 12f858dc9994..35fbd4d8ed4b 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -237,10 +237,10 @@ struct smi_info
237 237
238static int try_smi_init(struct smi_info *smi); 238static int try_smi_init(struct smi_info *smi);
239 239
240static struct notifier_block *xaction_notifier_list; 240static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
241static int register_xaction_notifier(struct notifier_block * nb) 241static int register_xaction_notifier(struct notifier_block * nb)
242{ 242{
243 return notifier_chain_register(&xaction_notifier_list, nb); 243 return atomic_notifier_chain_register(&xaction_notifier_list, nb);
244} 244}
245 245
246static void si_restart_short_timer(struct smi_info *smi_info); 246static void si_restart_short_timer(struct smi_info *smi_info);
@@ -302,7 +302,8 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
302 do_gettimeofday(&t); 302 do_gettimeofday(&t);
303 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); 303 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
304#endif 304#endif
305 err = notifier_call_chain(&xaction_notifier_list, 0, smi_info); 305 err = atomic_notifier_call_chain(&xaction_notifier_list,
306 0, smi_info);
306 if (err & NOTIFY_STOP_MASK) { 307 if (err & NOTIFY_STOP_MASK) {
307 rv = SI_SM_CALL_WITHOUT_DELAY; 308 rv = SI_SM_CALL_WITHOUT_DELAY;
308 goto out; 309 goto out;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 616539310d9a..7ece9f3c8f70 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -1158,7 +1158,8 @@ static int __init ipmi_wdog_init(void)
1158 } 1158 }
1159 1159
1160 register_reboot_notifier(&wdog_reboot_notifier); 1160 register_reboot_notifier(&wdog_reboot_notifier);
1161 notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier); 1161 atomic_notifier_chain_register(&panic_notifier_list,
1162 &wdog_panic_notifier);
1162 1163
1163 printk(KERN_INFO PFX "driver initialized\n"); 1164 printk(KERN_INFO PFX "driver initialized\n");
1164 1165
@@ -1176,7 +1177,8 @@ static __exit void ipmi_unregister_watchdog(void)
1176 release_nmi(&ipmi_nmi_handler); 1177 release_nmi(&ipmi_nmi_handler);
1177#endif 1178#endif
1178 1179
1179 notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); 1180 atomic_notifier_chain_unregister(&panic_notifier_list,
1181 &wdog_panic_notifier);
1180 unregister_reboot_notifier(&wdog_reboot_notifier); 1182 unregister_reboot_notifier(&wdog_reboot_notifier);
1181 1183
1182 if (! watchdog_user) 1184 if (! watchdog_user)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5245ba1649ed..66719f9d294c 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -899,7 +899,7 @@ static const struct {
899 unsigned int minor; 899 unsigned int minor;
900 char *name; 900 char *name;
901 umode_t mode; 901 umode_t mode;
902 struct file_operations *fops; 902 const struct file_operations *fops;
903} devlist[] = { /* list of minor devices */ 903} devlist[] = { /* list of minor devices */
904 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, 904 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
905 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, 905 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 3e4c0414a01a..96eb2a709e21 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -129,7 +129,7 @@ static int misc_open(struct inode * inode, struct file * file)
129 int minor = iminor(inode); 129 int minor = iminor(inode);
130 struct miscdevice *c; 130 struct miscdevice *c;
131 int err = -ENODEV; 131 int err = -ENODEV;
132 struct file_operations *old_fops, *new_fops = NULL; 132 const struct file_operations *old_fops, *new_fops = NULL;
133 133
134 down(&misc_sem); 134 down(&misc_sem);
135 135
diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h
index e7fd0b08e0b7..7e188a4d602a 100644
--- a/drivers/char/mxser.h
+++ b/drivers/char/mxser.h
@@ -118,7 +118,7 @@
118 118
119// enable CTS interrupt 119// enable CTS interrupt
120#define MOXA_MUST_IER_ECTSI 0x80 120#define MOXA_MUST_IER_ECTSI 0x80
121// eanble RTS interrupt 121// enable RTS interrupt
122#define MOXA_MUST_IER_ERTSI 0x40 122#define MOXA_MUST_IER_ERTSI 0x40
123// enable Xon/Xoff interrupt 123// enable Xon/Xoff interrupt
124#define MOXA_MUST_IER_XINT 0x20 124#define MOXA_MUST_IER_XINT 0x20
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index d68be61f0a49..fee2aca3f6a5 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -941,17 +941,6 @@ static void* mgsl_get_text_ptr(void)
941 return mgsl_get_text_ptr; 941 return mgsl_get_text_ptr;
942} 942}
943 943
944/*
945 * tmp_buf is used as a temporary buffer by mgsl_write. We need to
946 * lock it in case the COPY_FROM_USER blocks while swapping in a page,
947 * and some other program tries to do a serial write at the same time.
948 * Since the lock will only come under contention when the system is
949 * swapping and available memory is low, it makes sense to share one
950 * buffer across all the serial ioports, since it significantly saves
951 * memory if large numbers of serial ports are open.
952 */
953static unsigned char *tmp_buf;
954
955static inline int mgsl_paranoia_check(struct mgsl_struct *info, 944static inline int mgsl_paranoia_check(struct mgsl_struct *info,
956 char *name, const char *routine) 945 char *name, const char *routine)
957{ 946{
@@ -2150,7 +2139,7 @@ static int mgsl_write(struct tty_struct * tty,
2150 if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) 2139 if (mgsl_paranoia_check(info, tty->name, "mgsl_write"))
2151 goto cleanup; 2140 goto cleanup;
2152 2141
2153 if (!tty || !info->xmit_buf || !tmp_buf) 2142 if (!tty || !info->xmit_buf)
2154 goto cleanup; 2143 goto cleanup;
2155 2144
2156 if ( info->params.mode == MGSL_MODE_HDLC || 2145 if ( info->params.mode == MGSL_MODE_HDLC ||
@@ -3438,7 +3427,6 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
3438{ 3427{
3439 struct mgsl_struct *info; 3428 struct mgsl_struct *info;
3440 int retval, line; 3429 int retval, line;
3441 unsigned long page;
3442 unsigned long flags; 3430 unsigned long flags;
3443 3431
3444 /* verify range of specified line number */ 3432 /* verify range of specified line number */
@@ -3472,18 +3460,6 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
3472 goto cleanup; 3460 goto cleanup;
3473 } 3461 }
3474 3462
3475 if (!tmp_buf) {
3476 page = get_zeroed_page(GFP_KERNEL);
3477 if (!page) {
3478 retval = -ENOMEM;
3479 goto cleanup;
3480 }
3481 if (tmp_buf)
3482 free_page(page);
3483 else
3484 tmp_buf = (unsigned char *) page;
3485 }
3486
3487 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 3463 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
3488 3464
3489 spin_lock_irqsave(&info->netlock, flags); 3465 spin_lock_irqsave(&info->netlock, flags);
@@ -4502,11 +4478,6 @@ static void synclink_cleanup(void)
4502 kfree(tmp); 4478 kfree(tmp);
4503 } 4479 }
4504 4480
4505 if (tmp_buf) {
4506 free_page((unsigned long) tmp_buf);
4507 tmp_buf = NULL;
4508 }
4509
4510 if (pci_registered) 4481 if (pci_registered)
4511 pci_unregister_driver(&synclink_pci_driver); 4482 pci_unregister_driver(&synclink_pci_driver);
4512} 4483}
@@ -6025,7 +5996,7 @@ static void usc_set_async_mode( struct mgsl_struct *info )
6025 * <15..8> ? RxFIFO IRQ Request Level 5996 * <15..8> ? RxFIFO IRQ Request Level
6026 * 5997 *
6027 * Note: For async mode the receive FIFO level must be set 5998 * Note: For async mode the receive FIFO level must be set
6028 * to 0 to aviod the situation where the FIFO contains fewer bytes 5999 * to 0 to avoid the situation where the FIFO contains fewer bytes
6029 * than the trigger level and no more data is expected. 6000 * than the trigger level and no more data is expected.
6030 * 6001 *
6031 * <7> 0 Exited Hunt IA (Interrupt Arm) 6002 * <7> 0 Exited Hunt IA (Interrupt Arm)
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 738ec2f4e563..b4d1f4eea435 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: synclink_gt.c,v 4.22 2006/01/09 20:16:06 paulkf Exp $ 2 * $Id: synclink_gt.c,v 4.25 2006/02/06 21:20:33 paulkf Exp $
3 * 3 *
4 * Device driver for Microgate SyncLink GT serial adapters. 4 * Device driver for Microgate SyncLink GT serial adapters.
5 * 5 *
@@ -92,7 +92,7 @@
92 * module identification 92 * module identification
93 */ 93 */
94static char *driver_name = "SyncLink GT"; 94static char *driver_name = "SyncLink GT";
95static char *driver_version = "$Revision: 4.22 $"; 95static char *driver_version = "$Revision: 4.25 $";
96static char *tty_driver_name = "synclink_gt"; 96static char *tty_driver_name = "synclink_gt";
97static char *tty_dev_prefix = "ttySLG"; 97static char *tty_dev_prefix = "ttySLG";
98MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
@@ -188,6 +188,20 @@ static void hdlcdev_exit(struct slgt_info *info);
188#define SLGT_REG_SIZE 256 188#define SLGT_REG_SIZE 256
189 189
190/* 190/*
191 * conditional wait facility
192 */
193struct cond_wait {
194 struct cond_wait *next;
195 wait_queue_head_t q;
196 wait_queue_t wait;
197 unsigned int data;
198};
199static void init_cond_wait(struct cond_wait *w, unsigned int data);
200static void add_cond_wait(struct cond_wait **head, struct cond_wait *w);
201static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w);
202static void flush_cond_wait(struct cond_wait **head);
203
204/*
191 * DMA buffer descriptor and access macros 205 * DMA buffer descriptor and access macros
192 */ 206 */
193struct slgt_desc 207struct slgt_desc
@@ -269,6 +283,9 @@ struct slgt_info {
269 struct timer_list tx_timer; 283 struct timer_list tx_timer;
270 struct timer_list rx_timer; 284 struct timer_list rx_timer;
271 285
286 unsigned int gpio_present;
287 struct cond_wait *gpio_wait_q;
288
272 spinlock_t lock; /* spinlock for synchronizing with ISR */ 289 spinlock_t lock; /* spinlock for synchronizing with ISR */
273 290
274 struct work_struct task; 291 struct work_struct task;
@@ -379,6 +396,11 @@ static MGSL_PARAMS default_params = {
379#define MASK_OVERRUN BIT4 396#define MASK_OVERRUN BIT4
380 397
381#define GSR 0x00 /* global status */ 398#define GSR 0x00 /* global status */
399#define JCR 0x04 /* JTAG control */
400#define IODR 0x08 /* GPIO direction */
401#define IOER 0x0c /* GPIO interrupt enable */
402#define IOVR 0x10 /* GPIO value */
403#define IOSR 0x14 /* GPIO interrupt status */
382#define TDR 0x80 /* tx data */ 404#define TDR 0x80 /* tx data */
383#define RDR 0x80 /* rx data */ 405#define RDR 0x80 /* rx data */
384#define TCR 0x82 /* tx control */ 406#define TCR 0x82 /* tx control */
@@ -503,6 +525,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
503static void set_break(struct tty_struct *tty, int break_state); 525static void set_break(struct tty_struct *tty, int break_state);
504static int get_interface(struct slgt_info *info, int __user *if_mode); 526static int get_interface(struct slgt_info *info, int __user *if_mode);
505static int set_interface(struct slgt_info *info, int if_mode); 527static int set_interface(struct slgt_info *info, int if_mode);
528static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
529static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
530static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
506 531
507/* 532/*
508 * driver functions 533 * driver functions
@@ -1112,6 +1137,12 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1112 return get_interface(info, argp); 1137 return get_interface(info, argp);
1113 case MGSL_IOCSIF: 1138 case MGSL_IOCSIF:
1114 return set_interface(info,(int)arg); 1139 return set_interface(info,(int)arg);
1140 case MGSL_IOCSGPIO:
1141 return set_gpio(info, argp);
1142 case MGSL_IOCGGPIO:
1143 return get_gpio(info, argp);
1144 case MGSL_IOCWAITGPIO:
1145 return wait_gpio(info, argp);
1115 case TIOCGICOUNT: 1146 case TIOCGICOUNT:
1116 spin_lock_irqsave(&info->lock,flags); 1147 spin_lock_irqsave(&info->lock,flags);
1117 cnow = info->icount; 1148 cnow = info->icount;
@@ -1762,10 +1793,6 @@ static void rx_async(struct slgt_info *info)
1762 DBGDATA(info, p, count, "rx"); 1793 DBGDATA(info, p, count, "rx");
1763 1794
1764 for(i=0 ; i < count; i+=2, p+=2) { 1795 for(i=0 ; i < count; i+=2, p+=2) {
1765 if (tty && chars) {
1766 tty_flip_buffer_push(tty);
1767 chars = 0;
1768 }
1769 ch = *p; 1796 ch = *p;
1770 icount->rx++; 1797 icount->rx++;
1771 1798
@@ -2158,6 +2185,24 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
2158 } 2185 }
2159} 2186}
2160 2187
2188static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int state)
2189{
2190 struct cond_wait *w, *prev;
2191
2192 /* wake processes waiting for specific transitions */
2193 for (w = info->gpio_wait_q, prev = NULL ; w != NULL ; w = w->next) {
2194 if (w->data & changed) {
2195 w->data = state;
2196 wake_up_interruptible(&w->q);
2197 if (prev != NULL)
2198 prev->next = w->next;
2199 else
2200 info->gpio_wait_q = w->next;
2201 } else
2202 prev = w;
2203 }
2204}
2205
2161/* interrupt service routine 2206/* interrupt service routine
2162 * 2207 *
2163 * irq interrupt number 2208 * irq interrupt number
@@ -2193,6 +2238,22 @@ static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
2193 } 2238 }
2194 } 2239 }
2195 2240
2241 if (info->gpio_present) {
2242 unsigned int state;
2243 unsigned int changed;
2244 while ((changed = rd_reg32(info, IOSR)) != 0) {
2245 DBGISR(("%s iosr=%08x\n", info->device_name, changed));
2246 /* read latched state of GPIO signals */
2247 state = rd_reg32(info, IOVR);
2248 /* clear pending GPIO interrupt bits */
2249 wr_reg32(info, IOSR, changed);
2250 for (i=0 ; i < info->port_count ; i++) {
2251 if (info->port_array[i] != NULL)
2252 isr_gpio(info->port_array[i], changed, state);
2253 }
2254 }
2255 }
2256
2196 for(i=0; i < info->port_count ; i++) { 2257 for(i=0; i < info->port_count ; i++) {
2197 struct slgt_info *port = info->port_array[i]; 2258 struct slgt_info *port = info->port_array[i];
2198 2259
@@ -2276,6 +2337,8 @@ static void shutdown(struct slgt_info *info)
2276 set_signals(info); 2337 set_signals(info);
2277 } 2338 }
2278 2339
2340 flush_cond_wait(&info->gpio_wait_q);
2341
2279 spin_unlock_irqrestore(&info->lock,flags); 2342 spin_unlock_irqrestore(&info->lock,flags);
2280 2343
2281 if (info->tty) 2344 if (info->tty)
@@ -2650,6 +2713,175 @@ static int set_interface(struct slgt_info *info, int if_mode)
2650 return 0; 2713 return 0;
2651} 2714}
2652 2715
2716/*
2717 * set general purpose IO pin state and direction
2718 *
2719 * user_gpio fields:
2720 * state each bit indicates a pin state
2721 * smask set bit indicates pin state to set
2722 * dir each bit indicates a pin direction (0=input, 1=output)
2723 * dmask set bit indicates pin direction to set
2724 */
2725static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
2726{
2727 unsigned long flags;
2728 struct gpio_desc gpio;
2729 __u32 data;
2730
2731 if (!info->gpio_present)
2732 return -EINVAL;
2733 if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
2734 return -EFAULT;
2735 DBGINFO(("%s set_gpio state=%08x smask=%08x dir=%08x dmask=%08x\n",
2736 info->device_name, gpio.state, gpio.smask,
2737 gpio.dir, gpio.dmask));
2738
2739 spin_lock_irqsave(&info->lock,flags);
2740 if (gpio.dmask) {
2741 data = rd_reg32(info, IODR);
2742 data |= gpio.dmask & gpio.dir;
2743 data &= ~(gpio.dmask & ~gpio.dir);
2744 wr_reg32(info, IODR, data);
2745 }
2746 if (gpio.smask) {
2747 data = rd_reg32(info, IOVR);
2748 data |= gpio.smask & gpio.state;
2749 data &= ~(gpio.smask & ~gpio.state);
2750 wr_reg32(info, IOVR, data);
2751 }
2752 spin_unlock_irqrestore(&info->lock,flags);
2753
2754 return 0;
2755}
2756
2757/*
2758 * get general purpose IO pin state and direction
2759 */
2760static int get_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
2761{
2762 struct gpio_desc gpio;
2763 if (!info->gpio_present)
2764 return -EINVAL;
2765 gpio.state = rd_reg32(info, IOVR);
2766 gpio.smask = 0xffffffff;
2767 gpio.dir = rd_reg32(info, IODR);
2768 gpio.dmask = 0xffffffff;
2769 if (copy_to_user(user_gpio, &gpio, sizeof(gpio)))
2770 return -EFAULT;
2771 DBGINFO(("%s get_gpio state=%08x dir=%08x\n",
2772 info->device_name, gpio.state, gpio.dir));
2773 return 0;
2774}
2775
2776/*
2777 * conditional wait facility
2778 */
2779static void init_cond_wait(struct cond_wait *w, unsigned int data)
2780{
2781 init_waitqueue_head(&w->q);
2782 init_waitqueue_entry(&w->wait, current);
2783 w->data = data;
2784}
2785
2786static void add_cond_wait(struct cond_wait **head, struct cond_wait *w)
2787{
2788 set_current_state(TASK_INTERRUPTIBLE);
2789 add_wait_queue(&w->q, &w->wait);
2790 w->next = *head;
2791 *head = w;
2792}
2793
2794static void remove_cond_wait(struct cond_wait **head, struct cond_wait *cw)
2795{
2796 struct cond_wait *w, *prev;
2797 remove_wait_queue(&cw->q, &cw->wait);
2798 set_current_state(TASK_RUNNING);
2799 for (w = *head, prev = NULL ; w != NULL ; prev = w, w = w->next) {
2800 if (w == cw) {
2801 if (prev != NULL)
2802 prev->next = w->next;
2803 else
2804 *head = w->next;
2805 break;
2806 }
2807 }
2808}
2809
2810static void flush_cond_wait(struct cond_wait **head)
2811{
2812 while (*head != NULL) {
2813 wake_up_interruptible(&(*head)->q);
2814 *head = (*head)->next;
2815 }
2816}
2817
2818/*
2819 * wait for general purpose I/O pin(s) to enter specified state
2820 *
2821 * user_gpio fields:
2822 * state - bit indicates target pin state
2823 * smask - set bit indicates watched pin
2824 *
2825 * The wait ends when at least one watched pin enters the specified
2826 * state. When 0 (no error) is returned, user_gpio->state is set to the
2827 * state of all GPIO pins when the wait ends.
2828 *
2829 * Note: Each pin may be a dedicated input, dedicated output, or
2830 * configurable input/output. The number and configuration of pins
2831 * varies with the specific adapter model. Only input pins (dedicated
2832 * or configured) can be monitored with this function.
2833 */
2834static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
2835{
2836 unsigned long flags;
2837 int rc = 0;
2838 struct gpio_desc gpio;
2839 struct cond_wait wait;
2840 u32 state;
2841
2842 if (!info->gpio_present)
2843 return -EINVAL;
2844 if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
2845 return -EFAULT;
2846 DBGINFO(("%s wait_gpio() state=%08x smask=%08x\n",
2847 info->device_name, gpio.state, gpio.smask));
2848 /* ignore output pins identified by set IODR bit */
2849 if ((gpio.smask &= ~rd_reg32(info, IODR)) == 0)
2850 return -EINVAL;
2851 init_cond_wait(&wait, gpio.smask);
2852
2853 spin_lock_irqsave(&info->lock, flags);
2854 /* enable interrupts for watched pins */
2855 wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask);
2856 /* get current pin states */
2857 state = rd_reg32(info, IOVR);
2858
2859 if (gpio.smask & ~(state ^ gpio.state)) {
2860 /* already in target state */
2861 gpio.state = state;
2862 } else {
2863 /* wait for target state */
2864 add_cond_wait(&info->gpio_wait_q, &wait);
2865 spin_unlock_irqrestore(&info->lock, flags);
2866 schedule();
2867 if (signal_pending(current))
2868 rc = -ERESTARTSYS;
2869 else
2870 gpio.state = wait.data;
2871 spin_lock_irqsave(&info->lock, flags);
2872 remove_cond_wait(&info->gpio_wait_q, &wait);
2873 }
2874
2875 /* disable all GPIO interrupts if no waiting processes */
2876 if (info->gpio_wait_q == NULL)
2877 wr_reg32(info, IOER, 0);
2878 spin_unlock_irqrestore(&info->lock,flags);
2879
2880 if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio)))
2881 rc = -EFAULT;
2882 return rc;
2883}
2884
2653static int modem_input_wait(struct slgt_info *info,int arg) 2885static int modem_input_wait(struct slgt_info *info,int arg)
2654{ 2886{
2655 unsigned long flags; 2887 unsigned long flags;
@@ -3166,8 +3398,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
3166 } else { 3398 } else {
3167 port_array[0]->irq_requested = 1; 3399 port_array[0]->irq_requested = 1;
3168 adapter_test(port_array[0]); 3400 adapter_test(port_array[0]);
3169 for (i=1 ; i < port_count ; i++) 3401 for (i=1 ; i < port_count ; i++) {
3170 port_array[i]->init_error = port_array[0]->init_error; 3402 port_array[i]->init_error = port_array[0]->init_error;
3403 port_array[i]->gpio_present = port_array[0]->gpio_present;
3404 }
3171 } 3405 }
3172 } 3406 }
3173} 3407}
@@ -4301,7 +4535,7 @@ static int register_test(struct slgt_info *info)
4301 break; 4535 break;
4302 } 4536 }
4303 } 4537 }
4304 4538 info->gpio_present = (rd_reg32(info, JCR) & BIT5) ? 1 : 0;
4305 info->init_error = rc ? 0 : DiagStatus_AddressFailure; 4539 info->init_error = rc ? 0 : DiagStatus_AddressFailure;
4306 return rc; 4540 return rc;
4307} 4541}