Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e676253b authored by Ricardo Ribalda Delgado's avatar Ricardo Ribalda Delgado Committed by Greg Kroah-Hartman
Browse files

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: default avatarRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: default avatarAlan Cox <alan@linux.intel.com>
--
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: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 27d5775e
Loading
Loading
Loading
Loading
+39 −0
Original line number Original line Diff line number Diff line
@@ -2843,6 +2843,42 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
	return 0;
	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 *
static const char *
serial8250_type(struct uart_port *port)
serial8250_type(struct uart_port *port)
{
{
@@ -2872,6 +2908,7 @@ static struct uart_ops serial8250_pops = {
	.request_port	= serial8250_request_port,
	.request_port	= serial8250_request_port,
	.config_port	= serial8250_config_port,
	.config_port	= serial8250_config_port,
	.verify_port	= serial8250_verify_port,
	.verify_port	= serial8250_verify_port,
	.ioctl		= serial8250_ioctl,
#ifdef CONFIG_CONSOLE_POLL
#ifdef CONFIG_CONSOLE_POLL
	.poll_get_char = serial8250_get_poll_char,
	.poll_get_char = serial8250_get_poll_char,
	.poll_put_char = serial8250_put_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->port.fifosize	= up->port.fifosize;
		uart->tx_loadsz		= up->tx_loadsz;
		uart->tx_loadsz		= up->tx_loadsz;
		uart->capabilities	= up->capabilities;
		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 */
		/* Take tx_loadsz from fifosize if it wasn't set separately */
		if (uart->port.fifosize && !uart->tx_loadsz)
		if (uart->port.fifosize && !uart->tx_loadsz)
+3 −0
Original line number Original line Diff line number Diff line
@@ -96,10 +96,13 @@ struct uart_8250_port {
	unsigned char		msr_saved_flags;
	unsigned char		msr_saved_flags;


	struct uart_8250_dma	*dma;
	struct uart_8250_dma	*dma;
	struct serial_rs485     rs485;


	/* 8250 specific callbacks */
	/* 8250 specific callbacks */
	int			(*dl_read)(struct uart_8250_port *);
	int			(*dl_read)(struct uart_8250_port *);
	void			(*dl_write)(struct uart_8250_port *, int);
	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)
static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up)