aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/serial_core.c
diff options
context:
space:
mode:
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>2014-11-06 16:46:13 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-06 17:58:53 -0500
commita5f276f10ff70da89b349df445e944c8cd87956c (patch)
tree97654f0c9783f14136af81b33a8171deb62ba106 /drivers/tty/serial/serial_core.c
parent7f1dc2f384792f271833cd89a8608d189b63ea6d (diff)
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>
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r--drivers/tty/serial/serial_core.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index c5fb08cfbdb1..ab4db1dcc474 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1152,6 +1152,39 @@ static int uart_get_icount(struct tty_struct *tty,
1152 return 0; 1152 return 0;
1153} 1153}
1154 1154
1155static int uart_get_rs485_config(struct uart_port *port,
1156 struct serial_rs485 __user *rs485)
1157{
1158 if (!port->rs485_config)
1159 return -ENOIOCTLCMD;
1160
1161 if (copy_to_user(rs485, &port->rs485, sizeof(port->rs485)))
1162 return -EFAULT;
1163 return 0;
1164}
1165
1166static int uart_set_rs485_config(struct uart_port *port,
1167 struct serial_rs485 __user *rs485_user)
1168{
1169 struct serial_rs485 rs485;
1170 int ret;
1171
1172 if (!port->rs485_config)
1173 return -ENOIOCTLCMD;
1174
1175 if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user)))
1176 return -EFAULT;
1177
1178 ret = port->rs485_config(port, &rs485);
1179 if (ret)
1180 return ret;
1181
1182 if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485)))
1183 return -EFAULT;
1184
1185 return 0;
1186}
1187
1155/* 1188/*
1156 * Called via sys_ioctl. We can use spin_lock_irq() here. 1189 * Called via sys_ioctl. We can use spin_lock_irq() here.
1157 */ 1190 */
@@ -1223,6 +1256,18 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
1223 * protected against the tty being hung up. 1256 * protected against the tty being hung up.
1224 */ 1257 */
1225 switch (cmd) { 1258 switch (cmd) {
1259 case TIOCGRS485:
1260 ret = uart_get_rs485_config(state->uart_port, uarg);
1261 break;
1262
1263 case TIOCSRS485:
1264 ret = uart_set_rs485_config(state->uart_port, uarg);
1265 break;
1266 }
1267 if (ret != -ENOIOCTLCMD)
1268 goto out;
1269
1270 switch (cmd) {
1226 case TIOCSERGETLSR: /* Get line status register */ 1271 case TIOCSERGETLSR: /* Get line status register */
1227 ret = uart_get_lsr_info(tty, state, uarg); 1272 ret = uart_get_lsr_info(tty, state, uarg);
1228 break; 1273 break;