|
@@ -1152,6 +1152,39 @@ static int uart_get_icount(struct tty_struct *tty,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int uart_get_rs485_config(struct uart_port *port,
|
|
|
|
+ struct serial_rs485 __user *rs485)
|
|
|
|
+{
|
|
|
|
+ if (!port->rs485_config)
|
|
|
|
+ return -ENOIOCTLCMD;
|
|
|
|
+
|
|
|
|
+ if (copy_to_user(rs485, &port->rs485, sizeof(port->rs485)))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int uart_set_rs485_config(struct uart_port *port,
|
|
|
|
+ struct serial_rs485 __user *rs485_user)
|
|
|
|
+{
|
|
|
|
+ struct serial_rs485 rs485;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ if (!port->rs485_config)
|
|
|
|
+ return -ENOIOCTLCMD;
|
|
|
|
+
|
|
|
|
+ if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user)))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ ret = port->rs485_config(port, &rs485);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485)))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Called via sys_ioctl. We can use spin_lock_irq() here.
|
|
* Called via sys_ioctl. We can use spin_lock_irq() here.
|
|
*/
|
|
*/
|
|
@@ -1223,6 +1256,18 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
|
|
* protected against the tty being hung up.
|
|
* protected against the tty being hung up.
|
|
*/
|
|
*/
|
|
switch (cmd) {
|
|
switch (cmd) {
|
|
|
|
+ case TIOCGRS485:
|
|
|
|
+ ret = uart_get_rs485_config(state->uart_port, uarg);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case TIOCSRS485:
|
|
|
|
+ ret = uart_set_rs485_config(state->uart_port, uarg);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (ret != -ENOIOCTLCMD)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ switch (cmd) {
|
|
case TIOCSERGETLSR: /* Get line status register */
|
|
case TIOCSERGETLSR: /* Get line status register */
|
|
ret = uart_get_lsr_info(tty, state, uarg);
|
|
ret = uart_get_lsr_info(tty, state, uarg);
|
|
break;
|
|
break;
|