diff options
-rw-r--r-- | arch/cris/include/asm/ioctls.h | 5 | ||||
-rw-r--r-- | arch/cris/include/asm/rs485.h | 8 | ||||
-rw-r--r-- | arch/cris/include/asm/termios.h | 1 | ||||
-rw-r--r-- | drivers/serial/crisv10.c | 79 | ||||
-rw-r--r-- | drivers/serial/crisv10.h | 2 |
5 files changed, 66 insertions, 29 deletions
diff --git a/arch/cris/include/asm/ioctls.h b/arch/cris/include/asm/ioctls.h index 4f4e52531fa0..35bbc181598a 100644 --- a/arch/cris/include/asm/ioctls.h +++ b/arch/cris/include/asm/ioctls.h | |||
@@ -74,8 +74,9 @@ | |||
74 | #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ | 74 | #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ |
75 | #define FIOQSIZE 0x5460 | 75 | #define FIOQSIZE 0x5460 |
76 | 76 | ||
77 | #define TIOCSERSETRS485 0x5461 /* enable rs-485 */ | 77 | #define TIOCSERSETRS485 0x5461 /* enable rs-485 (deprecated) */ |
78 | #define TIOCSERWRRS485 0x5462 /* write rs-485 */ | 78 | #define TIOCSERWRRS485 0x5462 /* write rs-485 */ |
79 | #define TIOCSRS485 0x5463 /* enable rs-485 */ | ||
79 | 80 | ||
80 | /* Used for packet mode */ | 81 | /* Used for packet mode */ |
81 | #define TIOCPKT_DATA 0 | 82 | #define TIOCPKT_DATA 0 |
diff --git a/arch/cris/include/asm/rs485.h b/arch/cris/include/asm/rs485.h index c331c51b0c2b..ad40f9fbcb8a 100644 --- a/arch/cris/include/asm/rs485.h +++ b/arch/cris/include/asm/rs485.h | |||
@@ -1,15 +1,13 @@ | |||
1 | /* RS-485 structures */ | 1 | /* RS-485 structures */ |
2 | 2 | ||
3 | /* RS-485 support */ | 3 | /* Used with ioctl() TIOCSERSETRS485 for backward compatibility! |
4 | /* Used with ioctl() TIOCSERSETRS485 */ | 4 | * XXX: Do not use it for new code! |
5 | */ | ||
5 | struct rs485_control { | 6 | struct rs485_control { |
6 | unsigned short rts_on_send; | 7 | unsigned short rts_on_send; |
7 | unsigned short rts_after_sent; | 8 | unsigned short rts_after_sent; |
8 | unsigned long delay_rts_before_send; | 9 | unsigned long delay_rts_before_send; |
9 | unsigned short enabled; | 10 | unsigned short enabled; |
10 | #ifdef __KERNEL__ | ||
11 | int disable_serial_loopback; | ||
12 | #endif | ||
13 | }; | 11 | }; |
14 | 12 | ||
15 | /* Used with ioctl() TIOCSERWRRS485 */ | 13 | /* Used with ioctl() TIOCSERWRRS485 */ |
diff --git a/arch/cris/include/asm/termios.h b/arch/cris/include/asm/termios.h index b0124e6c2e41..1265109f4ce3 100644 --- a/arch/cris/include/asm/termios.h +++ b/arch/cris/include/asm/termios.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <asm/termbits.h> | 4 | #include <asm/termbits.h> |
5 | #include <asm/ioctls.h> | 5 | #include <asm/ioctls.h> |
6 | #include <asm/rs485.h> | 6 | #include <asm/rs485.h> |
7 | #include <linux/serial.h> | ||
7 | 8 | ||
8 | struct winsize { | 9 | struct winsize { |
9 | unsigned short ws_row; | 10 | unsigned short ws_row; |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index e642c22c80e2..7ba7d70f04d6 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -1391,7 +1391,7 @@ static inline void e100_disable_rx_irq(struct e100_serial *info) | |||
1391 | #if defined(CONFIG_ETRAX_RS485) | 1391 | #if defined(CONFIG_ETRAX_RS485) |
1392 | /* Enable RS-485 mode on selected port. This is UGLY. */ | 1392 | /* Enable RS-485 mode on selected port. This is UGLY. */ |
1393 | static int | 1393 | static int |
1394 | e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r) | 1394 | e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r) |
1395 | { | 1395 | { |
1396 | struct e100_serial * info = (struct e100_serial *)tty->driver_data; | 1396 | struct e100_serial * info = (struct e100_serial *)tty->driver_data; |
1397 | 1397 | ||
@@ -1409,13 +1409,11 @@ e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r) | |||
1409 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); | 1409 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); |
1410 | #endif | 1410 | #endif |
1411 | 1411 | ||
1412 | info->rs485.rts_on_send = 0x01 & r->rts_on_send; | 1412 | info->rs485.flags = r->flags; |
1413 | info->rs485.rts_after_sent = 0x01 & r->rts_after_sent; | ||
1414 | if (r->delay_rts_before_send >= 1000) | 1413 | if (r->delay_rts_before_send >= 1000) |
1415 | info->rs485.delay_rts_before_send = 1000; | 1414 | info->rs485.delay_rts_before_send = 1000; |
1416 | else | 1415 | else |
1417 | info->rs485.delay_rts_before_send = r->delay_rts_before_send; | 1416 | info->rs485.delay_rts_before_send = r->delay_rts_before_send; |
1418 | info->rs485.enabled = r->enabled; | ||
1419 | /* printk("rts: on send = %i, after = %i, enabled = %i", | 1417 | /* printk("rts: on send = %i, after = %i, enabled = %i", |
1420 | info->rs485.rts_on_send, | 1418 | info->rs485.rts_on_send, |
1421 | info->rs485.rts_after_sent, | 1419 | info->rs485.rts_after_sent, |
@@ -1430,17 +1428,18 @@ e100_write_rs485(struct tty_struct *tty, | |||
1430 | const unsigned char *buf, int count) | 1428 | const unsigned char *buf, int count) |
1431 | { | 1429 | { |
1432 | struct e100_serial * info = (struct e100_serial *)tty->driver_data; | 1430 | struct e100_serial * info = (struct e100_serial *)tty->driver_data; |
1433 | int old_enabled = info->rs485.enabled; | 1431 | int old_value = (info->rs485.flags) & SER_RS485_ENABLED; |
1434 | 1432 | ||
1435 | /* rs485 is always implicitly enabled if we're using the ioctl() | 1433 | /* rs485 is always implicitly enabled if we're using the ioctl() |
1436 | * but it doesn't have to be set in the rs485_control | 1434 | * but it doesn't have to be set in the serial_rs485 |
1437 | * (to be backward compatible with old apps) | 1435 | * (to be backward compatible with old apps) |
1438 | * So we store, set and restore it. | 1436 | * So we store, set and restore it. |
1439 | */ | 1437 | */ |
1440 | info->rs485.enabled = 1; | 1438 | info->rs485.flags |= SER_RS485_ENABLED; |
1441 | /* rs_write now deals with RS485 if enabled */ | 1439 | /* rs_write now deals with RS485 if enabled */ |
1442 | count = rs_write(tty, buf, count); | 1440 | count = rs_write(tty, buf, count); |
1443 | info->rs485.enabled = old_enabled; | 1441 | if (!old_value) |
1442 | info->rs485.flags &= ~(SER_RS485_ENABLED); | ||
1444 | return count; | 1443 | return count; |
1445 | } | 1444 | } |
1446 | 1445 | ||
@@ -1451,7 +1450,7 @@ static void rs485_toggle_rts_timer_function(unsigned long data) | |||
1451 | struct e100_serial *info = (struct e100_serial *)data; | 1450 | struct e100_serial *info = (struct e100_serial *)data; |
1452 | 1451 | ||
1453 | fast_timers_rs485[info->line].function = NULL; | 1452 | fast_timers_rs485[info->line].function = NULL; |
1454 | e100_rts(info, info->rs485.rts_after_sent); | 1453 | e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND)); |
1455 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) | 1454 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) |
1456 | e100_enable_rx(info); | 1455 | e100_enable_rx(info); |
1457 | e100_enable_rx_irq(info); | 1456 | e100_enable_rx_irq(info); |
@@ -1647,7 +1646,7 @@ transmit_chars_dma(struct e100_serial *info) | |||
1647 | info->tr_running = 0; | 1646 | info->tr_running = 0; |
1648 | 1647 | ||
1649 | #if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) | 1648 | #if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) |
1650 | if (info->rs485.enabled) { | 1649 | if (info->rs485.flags & SER_RS485_ENABLED) { |
1651 | /* Set a short timer to toggle RTS */ | 1650 | /* Set a short timer to toggle RTS */ |
1652 | start_one_shot_timer(&fast_timers_rs485[info->line], | 1651 | start_one_shot_timer(&fast_timers_rs485[info->line], |
1653 | rs485_toggle_rts_timer_function, | 1652 | rs485_toggle_rts_timer_function, |
@@ -2577,7 +2576,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) | |||
2577 | info->icount.tx++; | 2576 | info->icount.tx++; |
2578 | if (info->xmit.head == info->xmit.tail) { | 2577 | if (info->xmit.head == info->xmit.tail) { |
2579 | #if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) | 2578 | #if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) |
2580 | if (info->rs485.enabled) { | 2579 | if (info->rs485.flags & SER_RS485_ENABLED) { |
2581 | /* Set a short timer to toggle RTS */ | 2580 | /* Set a short timer to toggle RTS */ |
2582 | start_one_shot_timer(&fast_timers_rs485[info->line], | 2581 | start_one_shot_timer(&fast_timers_rs485[info->line], |
2583 | rs485_toggle_rts_timer_function, | 2582 | rs485_toggle_rts_timer_function, |
@@ -3218,7 +3217,7 @@ rs_write(struct tty_struct *tty, | |||
3218 | #if defined(CONFIG_ETRAX_RS485) | 3217 | #if defined(CONFIG_ETRAX_RS485) |
3219 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3218 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3220 | 3219 | ||
3221 | if (info->rs485.enabled) | 3220 | if (info->rs485.flags & SER_RS485_ENABLED) |
3222 | { | 3221 | { |
3223 | /* If we are in RS-485 mode, we need to toggle RTS and disable | 3222 | /* If we are in RS-485 mode, we need to toggle RTS and disable |
3224 | * the receiver before initiating a DMA transfer | 3223 | * the receiver before initiating a DMA transfer |
@@ -3228,7 +3227,7 @@ rs_write(struct tty_struct *tty, | |||
3228 | fast_timers_rs485[info->line].function = NULL; | 3227 | fast_timers_rs485[info->line].function = NULL; |
3229 | del_fast_timer(&fast_timers_rs485[info->line]); | 3228 | del_fast_timer(&fast_timers_rs485[info->line]); |
3230 | #endif | 3229 | #endif |
3231 | e100_rts(info, info->rs485.rts_on_send); | 3230 | e100_rts(info, (info->rs485.flags & SER_RS485_RTS_ON_SEND)); |
3232 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) | 3231 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) |
3233 | e100_disable_rx(info); | 3232 | e100_disable_rx(info); |
3234 | e100_enable_rx_irq(info); | 3233 | e100_enable_rx_irq(info); |
@@ -3242,7 +3241,7 @@ rs_write(struct tty_struct *tty, | |||
3242 | count = rs_raw_write(tty, buf, count); | 3241 | count = rs_raw_write(tty, buf, count); |
3243 | 3242 | ||
3244 | #if defined(CONFIG_ETRAX_RS485) | 3243 | #if defined(CONFIG_ETRAX_RS485) |
3245 | if (info->rs485.enabled) | 3244 | if (info->rs485.flags & SER_RS485_ENABLED) |
3246 | { | 3245 | { |
3247 | unsigned int val; | 3246 | unsigned int val; |
3248 | /* If we are in RS-485 mode the following has to be done: | 3247 | /* If we are in RS-485 mode the following has to be done: |
@@ -3263,7 +3262,7 @@ rs_write(struct tty_struct *tty, | |||
3263 | get_lsr_info(info, &val); | 3262 | get_lsr_info(info, &val); |
3264 | }while (!(val & TIOCSER_TEMT)); | 3263 | }while (!(val & TIOCSER_TEMT)); |
3265 | 3264 | ||
3266 | e100_rts(info, info->rs485.rts_after_sent); | 3265 | e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND)); |
3267 | 3266 | ||
3268 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) | 3267 | #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) |
3269 | e100_enable_rx(info); | 3268 | e100_enable_rx(info); |
@@ -3678,14 +3677,52 @@ rs_ioctl(struct tty_struct *tty, struct file * file, | |||
3678 | #if defined(CONFIG_ETRAX_RS485) | 3677 | #if defined(CONFIG_ETRAX_RS485) |
3679 | case TIOCSERSETRS485: | 3678 | case TIOCSERSETRS485: |
3680 | { | 3679 | { |
3680 | /* In this ioctl we still use the old structure | ||
3681 | * rs485_control for backward compatibility | ||
3682 | * (if we use serial_rs485, then old user-level code | ||
3683 | * wouldn't work anymore...). | ||
3684 | * The use of this ioctl is deprecated: use TIOCSRS485 | ||
3685 | * instead.*/ | ||
3681 | struct rs485_control rs485ctrl; | 3686 | struct rs485_control rs485ctrl; |
3687 | struct serial_rs485 rs485data; | ||
3688 | printk(KERN_DEBUG "The use of this ioctl is deprecated. Use TIOCSRS485 instead\n"); | ||
3682 | if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg, | 3689 | if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg, |
3683 | sizeof(rs485ctrl))) | 3690 | sizeof(rs485ctrl))) |
3684 | return -EFAULT; | 3691 | return -EFAULT; |
3685 | 3692 | ||
3686 | return e100_enable_rs485(tty, &rs485ctrl); | 3693 | rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; |
3694 | rs485data.flags = 0; | ||
3695 | if (rs485ctrl.enabled) | ||
3696 | rs485data.flags |= SER_RS485_ENABLED; | ||
3697 | else | ||
3698 | rs485data.flags &= ~(SER_RS485_ENABLED); | ||
3699 | |||
3700 | if (rs485ctrl.rts_on_send) | ||
3701 | rs485data.flags |= SER_RS485_RTS_ON_SEND; | ||
3702 | else | ||
3703 | rs485data.flags &= ~(SER_RS485_RTS_ON_SEND); | ||
3704 | |||
3705 | if (rs485ctrl.rts_after_sent) | ||
3706 | rs485data.flags |= SER_RS485_RTS_AFTER_SEND; | ||
3707 | else | ||
3708 | rs485data.flags &= ~(SER_RS485_RTS_AFTER_SEND); | ||
3709 | |||
3710 | return e100_enable_rs485(tty, &rs485data); | ||
3687 | } | 3711 | } |
3688 | 3712 | ||
3713 | case TIOCSRS485: | ||
3714 | { | ||
3715 | /* This is the new version of TIOCSRS485, with new | ||
3716 | * data structure serial_rs485 */ | ||
3717 | struct serial_rs485 rs485data; | ||
3718 | if (copy_from_user(&rs485data, (struct rs485_control *)arg, | ||
3719 | sizeof(rs485data))) | ||
3720 | return -EFAULT; | ||
3721 | |||
3722 | return e100_enable_rs485(tty, &rs485data); | ||
3723 | } | ||
3724 | |||
3725 | |||
3689 | case TIOCSERWRRS485: | 3726 | case TIOCSERWRRS485: |
3690 | { | 3727 | { |
3691 | struct rs485_write rs485wr; | 3728 | struct rs485_write rs485wr; |
@@ -3827,8 +3864,8 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3827 | /* port closed */ | 3864 | /* port closed */ |
3828 | 3865 | ||
3829 | #if defined(CONFIG_ETRAX_RS485) | 3866 | #if defined(CONFIG_ETRAX_RS485) |
3830 | if (info->rs485.enabled) { | 3867 | if (info->rs485.flags & SER_RS485_ENABLED) { |
3831 | info->rs485.enabled = 0; | 3868 | info->rs485.flags &= ~(SER_RS485_ENABLED); |
3832 | #if defined(CONFIG_ETRAX_RS485_ON_PA) | 3869 | #if defined(CONFIG_ETRAX_RS485_ON_PA) |
3833 | *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); | 3870 | *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); |
3834 | #endif | 3871 | #endif |
@@ -4493,10 +4530,10 @@ rs_init(void) | |||
4493 | 4530 | ||
4494 | #if defined(CONFIG_ETRAX_RS485) | 4531 | #if defined(CONFIG_ETRAX_RS485) |
4495 | /* Set sane defaults */ | 4532 | /* Set sane defaults */ |
4496 | info->rs485.rts_on_send = 0; | 4533 | info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); |
4497 | info->rs485.rts_after_sent = 1; | 4534 | info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; |
4498 | info->rs485.delay_rts_before_send = 0; | 4535 | info->rs485.delay_rts_before_send = 0; |
4499 | info->rs485.enabled = 0; | 4536 | info->rs485.flags &= ~(SER_RS485_ENABLED); |
4500 | #endif | 4537 | #endif |
4501 | INIT_WORK(&info->work, do_softint); | 4538 | INIT_WORK(&info->work, do_softint); |
4502 | 4539 | ||
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h index f36a729280bc..ea0beb46a10d 100644 --- a/drivers/serial/crisv10.h +++ b/drivers/serial/crisv10.h | |||
@@ -125,7 +125,7 @@ struct e100_serial { | |||
125 | int errorcode; | 125 | int errorcode; |
126 | 126 | ||
127 | #ifdef CONFIG_ETRAX_RS485 | 127 | #ifdef CONFIG_ETRAX_RS485 |
128 | struct rs485_control rs485; /* RS-485 support */ | 128 | struct serial_rs485 rs485; /* RS-485 support */ |
129 | #endif | 129 | #endif |
130 | }; | 130 | }; |
131 | 131 | ||