aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 6ec6e13d47d7..5e256494686a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -298,6 +298,7 @@ struct slgt_info {
298 298
299 unsigned int rbuf_fill_level; 299 unsigned int rbuf_fill_level;
300 unsigned int if_mode; 300 unsigned int if_mode;
301 unsigned int base_clock;
301 302
302 /* device status */ 303 /* device status */
303 304
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne
1156 return -EFAULT; 1157 return -EFAULT;
1157 1158
1158 spin_lock(&info->lock); 1159 spin_lock(&info->lock);
1159 info->params.mode = tmp_params.mode; 1160 if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) {
1160 info->params.loopback = tmp_params.loopback; 1161 info->base_clock = tmp_params.clock_speed;
1161 info->params.flags = tmp_params.flags; 1162 } else {
1162 info->params.encoding = tmp_params.encoding; 1163 info->params.mode = tmp_params.mode;
1163 info->params.clock_speed = tmp_params.clock_speed; 1164 info->params.loopback = tmp_params.loopback;
1164 info->params.addr_filter = tmp_params.addr_filter; 1165 info->params.flags = tmp_params.flags;
1165 info->params.crc_type = tmp_params.crc_type; 1166 info->params.encoding = tmp_params.encoding;
1166 info->params.preamble_length = tmp_params.preamble_length; 1167 info->params.clock_speed = tmp_params.clock_speed;
1167 info->params.preamble = tmp_params.preamble; 1168 info->params.addr_filter = tmp_params.addr_filter;
1168 info->params.data_rate = tmp_params.data_rate; 1169 info->params.crc_type = tmp_params.crc_type;
1169 info->params.data_bits = tmp_params.data_bits; 1170 info->params.preamble_length = tmp_params.preamble_length;
1170 info->params.stop_bits = tmp_params.stop_bits; 1171 info->params.preamble = tmp_params.preamble;
1171 info->params.parity = tmp_params.parity; 1172 info->params.data_rate = tmp_params.data_rate;
1173 info->params.data_bits = tmp_params.data_bits;
1174 info->params.stop_bits = tmp_params.stop_bits;
1175 info->params.parity = tmp_params.parity;
1176 }
1172 spin_unlock(&info->lock); 1177 spin_unlock(&info->lock);
1173 1178
1174 change_params(info); 1179 program_hw(info);
1175 1180
1176 return 0; 1181 return 0;
1177} 1182}
@@ -2559,10 +2564,13 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
2559 return -EFAULT; 2564 return -EFAULT;
2560 2565
2561 spin_lock_irqsave(&info->lock, flags); 2566 spin_lock_irqsave(&info->lock, flags);
2562 memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); 2567 if (tmp_params.mode == MGSL_MODE_BASE_CLOCK)
2568 info->base_clock = tmp_params.clock_speed;
2569 else
2570 memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
2563 spin_unlock_irqrestore(&info->lock, flags); 2571 spin_unlock_irqrestore(&info->lock, flags);
2564 2572
2565 change_params(info); 2573 program_hw(info);
2566 2574
2567 return 0; 2575 return 0;
2568} 2576}
@@ -3432,6 +3440,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
3432 info->magic = MGSL_MAGIC; 3440 info->magic = MGSL_MAGIC;
3433 INIT_WORK(&info->task, bh_handler); 3441 INIT_WORK(&info->task, bh_handler);
3434 info->max_frame_size = 4096; 3442 info->max_frame_size = 4096;
3443 info->base_clock = 14745600;
3435 info->rbuf_fill_level = DMABUFSIZE; 3444 info->rbuf_fill_level = DMABUFSIZE;
3436 info->port.close_delay = 5*HZ/10; 3445 info->port.close_delay = 5*HZ/10;
3437 info->port.closing_wait = 30*HZ; 3446 info->port.closing_wait = 30*HZ;
@@ -3779,7 +3788,7 @@ static void enable_loopback(struct slgt_info *info)
3779static void set_rate(struct slgt_info *info, u32 rate) 3788static void set_rate(struct slgt_info *info, u32 rate)
3780{ 3789{
3781 unsigned int div; 3790 unsigned int div;
3782 static unsigned int osc = 14745600; 3791 unsigned int osc = info->base_clock;
3783 3792
3784 /* div = osc/rate - 1 3793 /* div = osc/rate - 1
3785 * 3794 *
@@ -4083,18 +4092,27 @@ static void async_mode(struct slgt_info *info)
4083 * 06 CTS IRQ enable 4092 * 06 CTS IRQ enable
4084 * 05 DCD IRQ enable 4093 * 05 DCD IRQ enable
4085 * 04 RI IRQ enable 4094 * 04 RI IRQ enable
4086 * 03 reserved, must be zero 4095 * 03 0=16x sampling, 1=8x sampling
4087 * 02 1=txd->rxd internal loopback enable 4096 * 02 1=txd->rxd internal loopback enable
4088 * 01 reserved, must be zero 4097 * 01 reserved, must be zero
4089 * 00 1=master IRQ enable 4098 * 00 1=master IRQ enable
4090 */ 4099 */
4091 val = BIT15 + BIT14 + BIT0; 4100 val = BIT15 + BIT14 + BIT0;
4101 /* JCR[8] : 1 = x8 async mode feature available */
4102 if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate &&
4103 ((info->base_clock < (info->params.data_rate * 16)) ||
4104 (info->base_clock % (info->params.data_rate * 16)))) {
4105 /* use 8x sampling */
4106 val |= BIT3;
4107 set_rate(info, info->params.data_rate * 8);
4108 } else {
4109 /* use 16x sampling */
4110 set_rate(info, info->params.data_rate * 16);
4111 }
4092 wr_reg16(info, SCR, val); 4112 wr_reg16(info, SCR, val);
4093 4113
4094 slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); 4114 slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
4095 4115
4096 set_rate(info, info->params.data_rate * 16);
4097
4098 if (info->params.loopback) 4116 if (info->params.loopback)
4099 enable_loopback(info); 4117 enable_loopback(info);
4100} 4118}