From e676253b19b2d269cccf67fdb1592120a0cd0676 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Tue, 5 Aug 2014 11:45:59 +0200 Subject: [PATCH] serial/8250: Add support for RS485 IOCTLs This patch allow the users of the 8250 infrastructure to define a handler for RS485 configration. If no handler is defined the 8250 driver will work as usual. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Alan Cox -- v2:Change suggested by Alan "One Thousand Gnomes": - Move rs485 structure further down on the uart_8250_port structure drivers/tty/serial/8250/8250_core.c | 39 +++++++++++++++++++++++++++++++++++++ include/linux/serial_8250.h | 3 +++ 2 files changed, 42 insertions(+) Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 39 +++++++++++++++++++++++++++++ include/linux/serial_8250.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 1d42dba6121d..b28ed1beb50f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2843,6 +2843,42 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } +static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, + unsigned long arg) +{ + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + int ret; + struct serial_rs485 rs485_config; + + if (!up->rs485_config) + return -ENOIOCTLCMD; + + switch (cmd) { + case TIOCSRS485: + if (copy_from_user(&rs485_config, (void __user *)arg, + sizeof(rs485_config))) + return -EFAULT; + + ret = up->rs485_config(up, &rs485_config); + if (ret) + return ret; + + memcpy(&up->rs485, &rs485_config, sizeof(rs485_config)); + + return 0; + case TIOCGRS485: + if (copy_to_user((void __user *)arg, &up->rs485, + sizeof(up->rs485))) + return -EFAULT; + return 0; + default: + break; + } + + return -ENOIOCTLCMD; +} + static const char * serial8250_type(struct uart_port *port) { @@ -2872,6 +2908,7 @@ static struct uart_ops serial8250_pops = { .request_port = serial8250_request_port, .config_port = serial8250_config_port, .verify_port = serial8250_verify_port, + .ioctl = serial8250_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = serial8250_get_poll_char, .poll_put_char = serial8250_put_poll_char, @@ -3388,6 +3425,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart->port.fifosize = up->port.fifosize; uart->tx_loadsz = up->tx_loadsz; uart->capabilities = up->capabilities; + uart->rs485_config = up->rs485_config; + uart->rs485 = up->rs485; /* Take tx_loadsz from fifosize if it wasn't set separately */ if (uart->port.fifosize && !uart->tx_loadsz) diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index f93649e22c43..6dd671765312 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -96,10 +96,13 @@ struct uart_8250_port { unsigned char msr_saved_flags; struct uart_8250_dma *dma; + struct serial_rs485 rs485; /* 8250 specific callbacks */ int (*dl_read)(struct uart_8250_port *); void (*dl_write)(struct uart_8250_port *, int); + int (*rs485_config)(struct uart_8250_port *, + struct serial_rs485 *rs485); }; static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) -- 2.30.2