forked from Minki/linux
serial_core: Handle TIOC[GS]RS485 ioctls.
The following drivers: 8250_core, atmel_serial, max310x, mcf, omap-serial and sci16is7xx implement code to handle RS485 ioctls. In order to avoid code duplication, we implement a simple ioctl handler on the serial_core layer. This handler can be used by all the other drivers instead of duplicating code. Until this is the only RS485 ioctl handler, it will try first the rs485_config callback and if it is not present it will call the driver specific ioctl. Reviewed-by: Alan Cox <alan@linux.intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7f1dc2f384
commit
a5f276f10f
@ -1152,6 +1152,39 @@ static int uart_get_icount(struct tty_struct *tty,
|
||||
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.
|
||||
*/
|
||||
@ -1223,6 +1256,18 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
|
||||
* protected against the tty being hung up.
|
||||
*/
|
||||
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 */
|
||||
ret = uart_get_lsr_info(tty, state, uarg);
|
||||
break;
|
||||
|
@ -131,6 +131,8 @@ struct uart_port {
|
||||
void (*pm)(struct uart_port *, unsigned int state,
|
||||
unsigned int old);
|
||||
void (*handle_break)(struct uart_port *);
|
||||
int (*rs485_config)(struct uart_port *,
|
||||
struct serial_rs485 *rs485);
|
||||
unsigned int irq; /* irq number */
|
||||
unsigned long irqflags; /* irq flags */
|
||||
unsigned int uartclk; /* base uart clock */
|
||||
@ -231,6 +233,7 @@ struct uart_port {
|
||||
unsigned char unused[2];
|
||||
struct attribute_group *attr_group; /* port specific attributes */
|
||||
const struct attribute_group **tty_groups; /* all attributes (serial core use only) */
|
||||
struct serial_rs485 rs485;
|
||||
void *private_data; /* generic platform data pointer */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user