提交 9807224f 编写于 作者: P Paul Fulghum 提交者: Linus Torvalds

drivers/char/synclink_gt.c: add extended sync feature

Add support for extended byte synchronous mode feature of hardware.
Signed-off-by: NPaul Fulghum <paulkf@microgate.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 ed77ed61
...@@ -301,6 +301,8 @@ struct slgt_info { ...@@ -301,6 +301,8 @@ struct slgt_info {
unsigned int rx_pio; unsigned int rx_pio;
unsigned int if_mode; unsigned int if_mode;
unsigned int base_clock; unsigned int base_clock;
unsigned int xsync;
unsigned int xctrl;
/* device status */ /* device status */
...@@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = { ...@@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = {
#define TDCSR 0x94 /* tx DMA control/status */ #define TDCSR 0x94 /* tx DMA control/status */
#define RDDAR 0x98 /* rx DMA descriptor address */ #define RDDAR 0x98 /* rx DMA descriptor address */
#define TDDAR 0x9c /* tx DMA descriptor address */ #define TDDAR 0x9c /* tx DMA descriptor address */
#define XSR 0x40 /* extended sync pattern */
#define XCR 0x44 /* extended control */
#define RXIDLE BIT14 #define RXIDLE BIT14
#define RXBREAK BIT14 #define RXBREAK BIT14
...@@ -517,6 +521,10 @@ static int set_interface(struct slgt_info *info, int if_mode); ...@@ -517,6 +521,10 @@ 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 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 get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
static int get_xsync(struct slgt_info *info, int __user *if_mode);
static int set_xsync(struct slgt_info *info, int if_mode);
static int get_xctrl(struct slgt_info *info, int __user *if_mode);
static int set_xctrl(struct slgt_info *info, int if_mode);
/* /*
* driver functions * driver functions
...@@ -1056,6 +1064,14 @@ static int ioctl(struct tty_struct *tty, struct file *file, ...@@ -1056,6 +1064,14 @@ static int ioctl(struct tty_struct *tty, struct file *file,
return get_gpio(info, argp); return get_gpio(info, argp);
case MGSL_IOCWAITGPIO: case MGSL_IOCWAITGPIO:
return wait_gpio(info, argp); return wait_gpio(info, argp);
case MGSL_IOCGXSYNC:
return get_xsync(info, argp);
case MGSL_IOCSXSYNC:
return set_xsync(info, (int)arg);
case MGSL_IOCGXCTRL:
return get_xctrl(info, argp);
case MGSL_IOCSXCTRL:
return set_xctrl(info, (int)arg);
} }
mutex_lock(&info->port.mutex); mutex_lock(&info->port.mutex);
switch (cmd) { switch (cmd) {
...@@ -1213,12 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, ...@@ -1213,12 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
case MGSL_IOCSGPIO: case MGSL_IOCSGPIO:
case MGSL_IOCGGPIO: case MGSL_IOCGGPIO:
case MGSL_IOCWAITGPIO: case MGSL_IOCWAITGPIO:
case MGSL_IOCGXSYNC:
case MGSL_IOCGXCTRL:
case MGSL_IOCSTXIDLE: case MGSL_IOCSTXIDLE:
case MGSL_IOCTXENABLE: case MGSL_IOCTXENABLE:
case MGSL_IOCRXENABLE: case MGSL_IOCRXENABLE:
case MGSL_IOCTXABORT: case MGSL_IOCTXABORT:
case TIOCMIWAIT: case TIOCMIWAIT:
case MGSL_IOCSIF: case MGSL_IOCSIF:
case MGSL_IOCSXSYNC:
case MGSL_IOCSXCTRL:
rc = ioctl(tty, file, cmd, arg); rc = ioctl(tty, file, cmd, arg);
break; break;
} }
...@@ -1961,6 +1981,7 @@ static void bh_handler(struct work_struct *work) ...@@ -1961,6 +1981,7 @@ static void bh_handler(struct work_struct *work)
case MGSL_MODE_RAW: case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC: case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC: case MGSL_MODE_BISYNC:
case MGSL_MODE_XSYNC:
while(rx_get_buf(info)); while(rx_get_buf(info));
break; break;
} }
...@@ -2889,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode) ...@@ -2889,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode)
return 0; return 0;
} }
static int get_xsync(struct slgt_info *info, int __user *xsync)
{
DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync));
if (put_user(info->xsync, xsync))
return -EFAULT;
return 0;
}
/*
* set extended sync pattern (1 to 4 bytes) for extended sync mode
*
* sync pattern is contained in least significant bytes of value
* most significant byte of sync pattern is oldest (1st sent/detected)
*/
static int set_xsync(struct slgt_info *info, int xsync)
{
unsigned long flags;
DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync));
spin_lock_irqsave(&info->lock, flags);
info->xsync = xsync;
wr_reg32(info, XSR, xsync);
spin_unlock_irqrestore(&info->lock, flags);
return 0;
}
static int get_xctrl(struct slgt_info *info, int __user *xctrl)
{
DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl));
if (put_user(info->xctrl, xctrl))
return -EFAULT;
return 0;
}
/*
* set extended control options
*
* xctrl[31:19] reserved, must be zero
* xctrl[18:17] extended sync pattern length in bytes
* 00 = 1 byte in xsr[7:0]
* 01 = 2 bytes in xsr[15:0]
* 10 = 3 bytes in xsr[23:0]
* 11 = 4 bytes in xsr[31:0]
* xctrl[16] 1 = enable terminal count, 0=disabled
* xctrl[15:0] receive terminal count for fixed length packets
* value is count minus one (0 = 1 byte packet)
* when terminal count is reached, receiver
* automatically returns to hunt mode and receive
* FIFO contents are flushed to DMA buffers with
* end of frame (EOF) status
*/
static int set_xctrl(struct slgt_info *info, int xctrl)
{
unsigned long flags;
DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl));
spin_lock_irqsave(&info->lock, flags);
info->xctrl = xctrl;
wr_reg32(info, XCR, xctrl);
spin_unlock_irqrestore(&info->lock, flags);
return 0;
}
/* /*
* set general purpose IO pin state and direction * set general purpose IO pin state and direction
* *
...@@ -3768,7 +3852,9 @@ module_exit(slgt_exit); ...@@ -3768,7 +3852,9 @@ module_exit(slgt_exit);
#define CALC_REGADDR() \ #define CALC_REGADDR() \
unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \
if (addr >= 0x80) \ if (addr >= 0x80) \
reg_addr += (info->port_num) * 32; reg_addr += (info->port_num) * 32; \
else if (addr >= 0x40) \
reg_addr += (info->port_num) * 16;
static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) static __u8 rd_reg8(struct slgt_info *info, unsigned int addr)
{ {
...@@ -4187,7 +4273,13 @@ static void sync_mode(struct slgt_info *info) ...@@ -4187,7 +4273,13 @@ static void sync_mode(struct slgt_info *info)
/* TCR (tx control) /* TCR (tx control)
* *
* 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync * 15..13 mode
* 000=HDLC/SDLC
* 001=raw bit synchronous
* 010=asynchronous/isochronous
* 011=monosync byte synchronous
* 100=bisync byte synchronous
* 101=xsync byte synchronous
* 12..10 encoding * 12..10 encoding
* 09 CRC enable * 09 CRC enable
* 08 CRC32 * 08 CRC32
...@@ -4202,6 +4294,9 @@ static void sync_mode(struct slgt_info *info) ...@@ -4202,6 +4294,9 @@ static void sync_mode(struct slgt_info *info)
val = BIT2; val = BIT2;
switch(info->params.mode) { switch(info->params.mode) {
case MGSL_MODE_XSYNC:
val |= BIT15 + BIT13;
break;
case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
case MGSL_MODE_BISYNC: val |= BIT15; break; case MGSL_MODE_BISYNC: val |= BIT15; break;
case MGSL_MODE_RAW: val |= BIT13; break; case MGSL_MODE_RAW: val |= BIT13; break;
...@@ -4256,7 +4351,13 @@ static void sync_mode(struct slgt_info *info) ...@@ -4256,7 +4351,13 @@ static void sync_mode(struct slgt_info *info)
/* RCR (rx control) /* RCR (rx control)
* *
* 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync * 15..13 mode
* 000=HDLC/SDLC
* 001=raw bit synchronous
* 010=asynchronous/isochronous
* 011=monosync byte synchronous
* 100=bisync byte synchronous
* 101=xsync byte synchronous
* 12..10 encoding * 12..10 encoding
* 09 CRC enable * 09 CRC enable
* 08 CRC32 * 08 CRC32
...@@ -4268,6 +4369,9 @@ static void sync_mode(struct slgt_info *info) ...@@ -4268,6 +4369,9 @@ static void sync_mode(struct slgt_info *info)
val = 0; val = 0;
switch(info->params.mode) { switch(info->params.mode) {
case MGSL_MODE_XSYNC:
val |= BIT15 + BIT13;
break;
case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
case MGSL_MODE_BISYNC: val |= BIT15; break; case MGSL_MODE_BISYNC: val |= BIT15; break;
case MGSL_MODE_RAW: val |= BIT13; break; case MGSL_MODE_RAW: val |= BIT13; break;
...@@ -4684,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info) ...@@ -4684,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info)
switch(info->params.mode) { switch(info->params.mode) {
case MGSL_MODE_MONOSYNC: case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC: case MGSL_MODE_BISYNC:
case MGSL_MODE_XSYNC:
/* ignore residue in byte synchronous modes */ /* ignore residue in byte synchronous modes */
if (desc_residue(info->rbufs[i])) if (desc_residue(info->rbufs[i]))
count--; count--;
......
...@@ -126,6 +126,7 @@ ...@@ -126,6 +126,7 @@
#define MGSL_MODE_BISYNC 4 #define MGSL_MODE_BISYNC 4
#define MGSL_MODE_RAW 6 #define MGSL_MODE_RAW 6
#define MGSL_MODE_BASE_CLOCK 7 #define MGSL_MODE_BASE_CLOCK 7
#define MGSL_MODE_XSYNC 8
#define MGSL_BUS_TYPE_ISA 1 #define MGSL_BUS_TYPE_ISA 1
#define MGSL_BUS_TYPE_EISA 2 #define MGSL_BUS_TYPE_EISA 2
...@@ -290,6 +291,10 @@ struct gpio_desc { ...@@ -290,6 +291,10 @@ struct gpio_desc {
#define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc) #define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc)
#define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,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) #define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
#define MGSL_IOCSXSYNC _IO(MGSL_MAGIC_IOC, 19)
#define MGSL_IOCGXSYNC _IO(MGSL_MAGIC_IOC, 20)
#define MGSL_IOCSXCTRL _IO(MGSL_MAGIC_IOC, 21)
#define MGSL_IOCGXCTRL _IO(MGSL_MAGIC_IOC, 22)
#ifdef __KERNEL__ #ifdef __KERNEL__
/* provide 32 bit ioctl compatibility on 64 bit systems */ /* provide 32 bit ioctl compatibility on 64 bit systems */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册