forked from mirrors/linux
		
	[PATCH] synclink_gt add gpio feature
Add driver support for general purpose I/O feature of the Synclink GT adapters. Signed-off-by: Paul Fulghum <paulkf@micrgate.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									86a34147d1
								
							
						
					
					
						commit
						0080b7aae8
					
				
					 2 changed files with 252 additions and 5 deletions
				
			
		| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: synclink_gt.c,v 4.22 2006/01/09 20:16:06 paulkf Exp $
 | 
					 * $Id: synclink_gt.c,v 4.25 2006/02/06 21:20:33 paulkf Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Device driver for Microgate SyncLink GT serial adapters.
 | 
					 * Device driver for Microgate SyncLink GT serial adapters.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@
 | 
				
			||||||
 * module identification
 | 
					 * module identification
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static char *driver_name     = "SyncLink GT";
 | 
					static char *driver_name     = "SyncLink GT";
 | 
				
			||||||
static char *driver_version  = "$Revision: 4.22 $";
 | 
					static char *driver_version  = "$Revision: 4.25 $";
 | 
				
			||||||
static char *tty_driver_name = "synclink_gt";
 | 
					static char *tty_driver_name = "synclink_gt";
 | 
				
			||||||
static char *tty_dev_prefix  = "ttySLG";
 | 
					static char *tty_dev_prefix  = "ttySLG";
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
| 
						 | 
					@ -187,6 +187,20 @@ static void hdlcdev_exit(struct slgt_info *info);
 | 
				
			||||||
#define SLGT_MAX_PORTS 4
 | 
					#define SLGT_MAX_PORTS 4
 | 
				
			||||||
#define SLGT_REG_SIZE  256
 | 
					#define SLGT_REG_SIZE  256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * conditional wait facility
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct cond_wait {
 | 
				
			||||||
 | 
						struct cond_wait *next;
 | 
				
			||||||
 | 
						wait_queue_head_t q;
 | 
				
			||||||
 | 
						wait_queue_t wait;
 | 
				
			||||||
 | 
						unsigned int data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static void init_cond_wait(struct cond_wait *w, unsigned int data);
 | 
				
			||||||
 | 
					static void add_cond_wait(struct cond_wait **head, struct cond_wait *w);
 | 
				
			||||||
 | 
					static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w);
 | 
				
			||||||
 | 
					static void flush_cond_wait(struct cond_wait **head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * DMA buffer descriptor and access macros
 | 
					 * DMA buffer descriptor and access macros
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -269,6 +283,9 @@ struct slgt_info {
 | 
				
			||||||
	struct timer_list	tx_timer;
 | 
						struct timer_list	tx_timer;
 | 
				
			||||||
	struct timer_list	rx_timer;
 | 
						struct timer_list	rx_timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int            gpio_present;
 | 
				
			||||||
 | 
						struct cond_wait        *gpio_wait_q;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spinlock_t lock;	/* spinlock for synchronizing with ISR */
 | 
						spinlock_t lock;	/* spinlock for synchronizing with ISR */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct work_struct task;
 | 
						struct work_struct task;
 | 
				
			||||||
| 
						 | 
					@ -379,6 +396,11 @@ static MGSL_PARAMS default_params = {
 | 
				
			||||||
#define MASK_OVERRUN BIT4
 | 
					#define MASK_OVERRUN BIT4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSR   0x00 /* global status */
 | 
					#define GSR   0x00 /* global status */
 | 
				
			||||||
 | 
					#define JCR   0x04 /* JTAG control */
 | 
				
			||||||
 | 
					#define IODR  0x08 /* GPIO direction */
 | 
				
			||||||
 | 
					#define IOER  0x0c /* GPIO interrupt enable */
 | 
				
			||||||
 | 
					#define IOVR  0x10 /* GPIO value */
 | 
				
			||||||
 | 
					#define IOSR  0x14 /* GPIO interrupt status */
 | 
				
			||||||
#define TDR   0x80 /* tx data */
 | 
					#define TDR   0x80 /* tx data */
 | 
				
			||||||
#define RDR   0x80 /* rx data */
 | 
					#define RDR   0x80 /* rx data */
 | 
				
			||||||
#define TCR   0x82 /* tx control */
 | 
					#define TCR   0x82 /* tx control */
 | 
				
			||||||
| 
						 | 
					@ -503,6 +525,9 @@ static int  tiocmset(struct tty_struct *tty, struct file *file,
 | 
				
			||||||
static void set_break(struct tty_struct *tty, int break_state);
 | 
					static void set_break(struct tty_struct *tty, int break_state);
 | 
				
			||||||
static int  get_interface(struct slgt_info *info, int __user *if_mode);
 | 
					static int  get_interface(struct slgt_info *info, int __user *if_mode);
 | 
				
			||||||
static int  set_interface(struct slgt_info *info, int if_mode);
 | 
					static int  set_interface(struct slgt_info *info, int if_mode);
 | 
				
			||||||
 | 
					static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 | 
				
			||||||
 | 
					static int  get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 | 
				
			||||||
 | 
					static int  wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * driver functions
 | 
					 * driver functions
 | 
				
			||||||
| 
						 | 
					@ -1112,6 +1137,12 @@ static int ioctl(struct tty_struct *tty, struct file *file,
 | 
				
			||||||
		return get_interface(info, argp);
 | 
							return get_interface(info, argp);
 | 
				
			||||||
	case MGSL_IOCSIF:
 | 
						case MGSL_IOCSIF:
 | 
				
			||||||
		return set_interface(info,(int)arg);
 | 
							return set_interface(info,(int)arg);
 | 
				
			||||||
 | 
						case MGSL_IOCSGPIO:
 | 
				
			||||||
 | 
							return set_gpio(info, argp);
 | 
				
			||||||
 | 
						case MGSL_IOCGGPIO:
 | 
				
			||||||
 | 
							return get_gpio(info, argp);
 | 
				
			||||||
 | 
						case MGSL_IOCWAITGPIO:
 | 
				
			||||||
 | 
							return wait_gpio(info, argp);
 | 
				
			||||||
	case TIOCGICOUNT:
 | 
						case TIOCGICOUNT:
 | 
				
			||||||
		spin_lock_irqsave(&info->lock,flags);
 | 
							spin_lock_irqsave(&info->lock,flags);
 | 
				
			||||||
		cnow = info->icount;
 | 
							cnow = info->icount;
 | 
				
			||||||
| 
						 | 
					@ -2158,6 +2189,24 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cond_wait *w, *prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* wake processes waiting for specific transitions */
 | 
				
			||||||
 | 
						for (w = info->gpio_wait_q, prev = NULL ; w != NULL ; w = w->next) {
 | 
				
			||||||
 | 
							if (w->data & changed) {
 | 
				
			||||||
 | 
								w->data = state;
 | 
				
			||||||
 | 
								wake_up_interruptible(&w->q);
 | 
				
			||||||
 | 
								if (prev != NULL)
 | 
				
			||||||
 | 
									prev->next = w->next;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									info->gpio_wait_q = w->next;
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								prev = w;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* interrupt service routine
 | 
					/* interrupt service routine
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * 	irq	interrupt number
 | 
					 * 	irq	interrupt number
 | 
				
			||||||
| 
						 | 
					@ -2193,6 +2242,22 @@ static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (info->gpio_present) {
 | 
				
			||||||
 | 
							unsigned int state;
 | 
				
			||||||
 | 
							unsigned int changed;
 | 
				
			||||||
 | 
							while ((changed = rd_reg32(info, IOSR)) != 0) {
 | 
				
			||||||
 | 
								DBGISR(("%s iosr=%08x\n", info->device_name, changed));
 | 
				
			||||||
 | 
								/* read latched state of GPIO signals */
 | 
				
			||||||
 | 
								state = rd_reg32(info, IOVR);
 | 
				
			||||||
 | 
								/* clear pending GPIO interrupt bits */
 | 
				
			||||||
 | 
								wr_reg32(info, IOSR, changed);
 | 
				
			||||||
 | 
								for (i=0 ; i < info->port_count ; i++) {
 | 
				
			||||||
 | 
									if (info->port_array[i] != NULL)
 | 
				
			||||||
 | 
										isr_gpio(info->port_array[i], changed, state);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(i=0; i < info->port_count ; i++) {
 | 
						for(i=0; i < info->port_count ; i++) {
 | 
				
			||||||
		struct slgt_info *port = info->port_array[i];
 | 
							struct slgt_info *port = info->port_array[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2276,6 +2341,8 @@ static void shutdown(struct slgt_info *info)
 | 
				
			||||||
		set_signals(info);
 | 
							set_signals(info);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flush_cond_wait(&info->gpio_wait_q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&info->lock,flags);
 | 
						spin_unlock_irqrestore(&info->lock,flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (info->tty)
 | 
						if (info->tty)
 | 
				
			||||||
| 
						 | 
					@ -2650,6 +2717,175 @@ static int set_interface(struct slgt_info *info, int if_mode)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * set general purpose IO pin state and direction
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * user_gpio fields:
 | 
				
			||||||
 | 
					 * state   each bit indicates a pin state
 | 
				
			||||||
 | 
					 * smask   set bit indicates pin state to set
 | 
				
			||||||
 | 
					 * dir     each bit indicates a pin direction (0=input, 1=output)
 | 
				
			||||||
 | 
					 * dmask   set bit indicates pin direction to set
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 	unsigned long flags;
 | 
				
			||||||
 | 
						struct gpio_desc gpio;
 | 
				
			||||||
 | 
						__u32 data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!info->gpio_present)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
						DBGINFO(("%s set_gpio state=%08x smask=%08x dir=%08x dmask=%08x\n",
 | 
				
			||||||
 | 
							 info->device_name, gpio.state, gpio.smask,
 | 
				
			||||||
 | 
							 gpio.dir, gpio.dmask));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irqsave(&info->lock,flags);
 | 
				
			||||||
 | 
						if (gpio.dmask) {
 | 
				
			||||||
 | 
							data = rd_reg32(info, IODR);
 | 
				
			||||||
 | 
							data |= gpio.dmask & gpio.dir;
 | 
				
			||||||
 | 
							data &= ~(gpio.dmask & ~gpio.dir);
 | 
				
			||||||
 | 
							wr_reg32(info, IODR, data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (gpio.smask) {
 | 
				
			||||||
 | 
							data = rd_reg32(info, IOVR);
 | 
				
			||||||
 | 
							data |= gpio.smask & gpio.state;
 | 
				
			||||||
 | 
							data &= ~(gpio.smask & ~gpio.state);
 | 
				
			||||||
 | 
							wr_reg32(info, IOVR, data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&info->lock,flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * get general purpose IO pin state and direction
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int get_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gpio_desc gpio;
 | 
				
			||||||
 | 
						if (!info->gpio_present)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						gpio.state = rd_reg32(info, IOVR);
 | 
				
			||||||
 | 
						gpio.smask = 0xffffffff;
 | 
				
			||||||
 | 
						gpio.dir   = rd_reg32(info, IODR);
 | 
				
			||||||
 | 
						gpio.dmask = 0xffffffff;
 | 
				
			||||||
 | 
						if (copy_to_user(user_gpio, &gpio, sizeof(gpio)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
						DBGINFO(("%s get_gpio state=%08x dir=%08x\n",
 | 
				
			||||||
 | 
							 info->device_name, gpio.state, gpio.dir));
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * conditional wait facility
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void init_cond_wait(struct cond_wait *w, unsigned int data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						init_waitqueue_head(&w->q);
 | 
				
			||||||
 | 
						init_waitqueue_entry(&w->wait, current);
 | 
				
			||||||
 | 
						w->data = data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void add_cond_wait(struct cond_wait **head, struct cond_wait *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						set_current_state(TASK_INTERRUPTIBLE);
 | 
				
			||||||
 | 
						add_wait_queue(&w->q, &w->wait);
 | 
				
			||||||
 | 
						w->next = *head;
 | 
				
			||||||
 | 
						*head = w;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void remove_cond_wait(struct cond_wait **head, struct cond_wait *cw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cond_wait *w, *prev;
 | 
				
			||||||
 | 
						remove_wait_queue(&cw->q, &cw->wait);
 | 
				
			||||||
 | 
						set_current_state(TASK_RUNNING);
 | 
				
			||||||
 | 
						for (w = *head, prev = NULL ; w != NULL ; prev = w, w = w->next) {
 | 
				
			||||||
 | 
							if (w == cw) {
 | 
				
			||||||
 | 
								if (prev != NULL)
 | 
				
			||||||
 | 
									prev->next = w->next;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									*head = w->next;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void flush_cond_wait(struct cond_wait **head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (*head != NULL) {
 | 
				
			||||||
 | 
							wake_up_interruptible(&(*head)->q);
 | 
				
			||||||
 | 
							*head = (*head)->next;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * wait for general purpose I/O pin(s) to enter specified state
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * user_gpio fields:
 | 
				
			||||||
 | 
					 * state - bit indicates target pin state
 | 
				
			||||||
 | 
					 * smask - set bit indicates watched pin
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The wait ends when at least one watched pin enters the specified
 | 
				
			||||||
 | 
					 * state. When 0 (no error) is returned, user_gpio->state is set to the
 | 
				
			||||||
 | 
					 * state of all GPIO pins when the wait ends.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: Each pin may be a dedicated input, dedicated output, or
 | 
				
			||||||
 | 
					 * configurable input/output. The number and configuration of pins
 | 
				
			||||||
 | 
					 * varies with the specific adapter model. Only input pins (dedicated
 | 
				
			||||||
 | 
					 * or configured) can be monitored with this function.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 	unsigned long flags;
 | 
				
			||||||
 | 
						int rc = 0;
 | 
				
			||||||
 | 
						struct gpio_desc gpio;
 | 
				
			||||||
 | 
						struct cond_wait wait;
 | 
				
			||||||
 | 
						u32 state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!info->gpio_present)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
						DBGINFO(("%s wait_gpio() state=%08x smask=%08x\n",
 | 
				
			||||||
 | 
							 info->device_name, gpio.state, gpio.smask));
 | 
				
			||||||
 | 
						/* ignore output pins identified by set IODR bit */
 | 
				
			||||||
 | 
						if ((gpio.smask &= ~rd_reg32(info, IODR)) == 0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						init_cond_wait(&wait, gpio.smask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irqsave(&info->lock, flags);
 | 
				
			||||||
 | 
						/* enable interrupts for watched pins */
 | 
				
			||||||
 | 
						wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask);
 | 
				
			||||||
 | 
						/* get current pin states */
 | 
				
			||||||
 | 
						state = rd_reg32(info, IOVR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gpio.smask & ~(state ^ gpio.state)) {
 | 
				
			||||||
 | 
							/* already in target state */
 | 
				
			||||||
 | 
							gpio.state = state;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/* wait for target state */
 | 
				
			||||||
 | 
							add_cond_wait(&info->gpio_wait_q, &wait);
 | 
				
			||||||
 | 
							spin_unlock_irqrestore(&info->lock, flags);
 | 
				
			||||||
 | 
							schedule();
 | 
				
			||||||
 | 
							if (signal_pending(current))
 | 
				
			||||||
 | 
								rc = -ERESTARTSYS;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								gpio.state = wait.data;
 | 
				
			||||||
 | 
							spin_lock_irqsave(&info->lock, flags);
 | 
				
			||||||
 | 
							remove_cond_wait(&info->gpio_wait_q, &wait);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* disable all GPIO interrupts if no waiting processes */
 | 
				
			||||||
 | 
						if (info->gpio_wait_q == NULL)
 | 
				
			||||||
 | 
							wr_reg32(info, IOER, 0);
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&info->lock,flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio)))
 | 
				
			||||||
 | 
							rc = -EFAULT;
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int modem_input_wait(struct slgt_info *info,int arg)
 | 
					static int modem_input_wait(struct slgt_info *info,int arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 	unsigned long flags;
 | 
					 	unsigned long flags;
 | 
				
			||||||
| 
						 | 
					@ -3166,8 +3402,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			port_array[0]->irq_requested = 1;
 | 
								port_array[0]->irq_requested = 1;
 | 
				
			||||||
			adapter_test(port_array[0]);
 | 
								adapter_test(port_array[0]);
 | 
				
			||||||
			for (i=1 ; i < port_count ; i++)
 | 
								for (i=1 ; i < port_count ; i++) {
 | 
				
			||||||
				port_array[i]->init_error = port_array[0]->init_error;
 | 
									port_array[i]->init_error = port_array[0]->init_error;
 | 
				
			||||||
 | 
									port_array[i]->gpio_present = port_array[0]->gpio_present;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4301,7 +4539,7 @@ static int register_test(struct slgt_info *info)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						info->gpio_present = (rd_reg32(info, JCR) & BIT5) ? 1 : 0;
 | 
				
			||||||
	info->init_error = rc ? 0 : DiagStatus_AddressFailure;
 | 
						info->init_error = rc ? 0 : DiagStatus_AddressFailure;
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * SyncLink Multiprotocol Serial Adapter Driver
 | 
					 * SyncLink Multiprotocol Serial Adapter Driver
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: synclink.h,v 3.10 2005/11/08 19:50:54 paulkf Exp $
 | 
					 * $Id: synclink.h,v 3.11 2006/02/06 21:20:29 paulkf Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Copyright (C) 1998-2000 by Microgate Corporation
 | 
					 * Copyright (C) 1998-2000 by Microgate Corporation
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -221,6 +221,12 @@ struct mgsl_icount {
 | 
				
			||||||
	__u32	rxidle;
 | 
						__u32	rxidle;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gpio_desc {
 | 
				
			||||||
 | 
						__u32 state;
 | 
				
			||||||
 | 
						__u32 smask;
 | 
				
			||||||
 | 
						__u32 dir;
 | 
				
			||||||
 | 
						__u32 dmask;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEBUG_LEVEL_DATA	1
 | 
					#define DEBUG_LEVEL_DATA	1
 | 
				
			||||||
#define DEBUG_LEVEL_ERROR 	2
 | 
					#define DEBUG_LEVEL_ERROR 	2
 | 
				
			||||||
| 
						 | 
					@ -276,5 +282,8 @@ struct mgsl_icount {
 | 
				
			||||||
#define MGSL_IOCLOOPTXDONE	_IO(MGSL_MAGIC_IOC,9)
 | 
					#define MGSL_IOCLOOPTXDONE	_IO(MGSL_MAGIC_IOC,9)
 | 
				
			||||||
#define MGSL_IOCSIF		_IO(MGSL_MAGIC_IOC,10)
 | 
					#define MGSL_IOCSIF		_IO(MGSL_MAGIC_IOC,10)
 | 
				
			||||||
#define MGSL_IOCGIF		_IO(MGSL_MAGIC_IOC,11)
 | 
					#define MGSL_IOCGIF		_IO(MGSL_MAGIC_IOC,11)
 | 
				
			||||||
 | 
					#define MGSL_IOCSGPIO		_IOW(MGSL_MAGIC_IOC,16,struct gpio_desc)
 | 
				
			||||||
 | 
					#define MGSL_IOCGGPIO		_IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)
 | 
				
			||||||
 | 
					#define MGSL_IOCWAITGPIO	_IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _SYNCLINK_H_ */
 | 
					#endif /* _SYNCLINK_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue