aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/serial_core.c45
-rw-r--r--include/linux/serial_core.h3
2 files changed, 48 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;
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 40b4cc4f8e1d..3231a43f6acf 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -131,6 +131,8 @@ struct uart_port {
131 void (*pm)(struct uart_port *, unsigned int state, 131 void (*pm)(struct uart_port *, unsigned int state,
132 unsigned int old); 132 unsigned int old);
133 void (*handle_break)(struct uart_port *); 133 void (*handle_break)(struct uart_port *);
134 int (*rs485_config)(struct uart_port *,
135 struct serial_rs485 *rs485);
134 unsigned int irq; /* irq number */ 136 unsigned int irq; /* irq number */
135 unsigned long irqflags; /* irq flags */ 137 unsigned long irqflags; /* irq flags */
136 unsigned int uartclk; /* base uart clock */ 138 unsigned int uartclk; /* base uart clock */
@@ -231,6 +233,7 @@ struct uart_port {
231 unsigned char unused[2]; 233 unsigned char unused[2];
232 struct attribute_group *attr_group; /* port specific attributes */ 234 struct attribute_group *attr_group; /* port specific attributes */
233 const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ 235 const struct attribute_group **tty_groups; /* all attributes (serial core use only) */
236 struct serial_rs485 rs485;
234 void *private_data; /* generic platform data pointer */ 237 void *private_data; /* generic platform data pointer */
235}; 238};
236 239