diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2014-11-06 16:46:13 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-06 17:58:53 -0500 |
commit | a5f276f10ff70da89b349df445e944c8cd87956c (patch) | |
tree | 97654f0c9783f14136af81b33a8171deb62ba106 /drivers/tty/serial/serial_core.c | |
parent | 7f1dc2f384792f271833cd89a8608d189b63ea6d (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.c | 45 |
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 | ||
1155 | static 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 | |||
1166 | static 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; |