.. | .. |
---|
14 | 14 | #include <linux/sched/signal.h> |
---|
15 | 15 | #include <linux/init.h> |
---|
16 | 16 | #include <linux/console.h> |
---|
| 17 | +#include <linux/gpio/consumer.h> |
---|
17 | 18 | #include <linux/of.h> |
---|
18 | 19 | #include <linux/proc_fs.h> |
---|
19 | 20 | #include <linux/seq_file.h> |
---|
20 | 21 | #include <linux/device.h> |
---|
21 | 22 | #include <linux/serial.h> /* for serial_state and serial_icounter_struct */ |
---|
22 | 23 | #include <linux/serial_core.h> |
---|
| 24 | +#include <linux/sysrq.h> |
---|
23 | 25 | #include <linux/delay.h> |
---|
24 | 26 | #include <linux/mutex.h> |
---|
| 27 | +#include <linux/security.h> |
---|
25 | 28 | |
---|
26 | 29 | #include <linux/irq.h> |
---|
27 | 30 | #include <linux/uaccess.h> |
---|
.. | .. |
---|
38 | 41 | static struct lock_class_key port_lock_key; |
---|
39 | 42 | |
---|
40 | 43 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) |
---|
| 44 | + |
---|
| 45 | +/* |
---|
| 46 | + * Max time with active RTS before/after data is sent. |
---|
| 47 | + */ |
---|
| 48 | +#define RS485_MAX_RTS_DELAY 100 /* msecs */ |
---|
41 | 49 | |
---|
42 | 50 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
---|
43 | 51 | struct ktermios *old_termios); |
---|
.. | .. |
---|
144 | 152 | spin_lock_irqsave(&port->lock, flags); |
---|
145 | 153 | old = port->mctrl; |
---|
146 | 154 | port->mctrl = (old & ~clear) | set; |
---|
147 | | - if (old != port->mctrl) |
---|
| 155 | + if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED)) |
---|
148 | 156 | port->ops->set_mctrl(port, port->mctrl); |
---|
149 | 157 | spin_unlock_irqrestore(&port->lock, flags); |
---|
150 | 158 | } |
---|
.. | .. |
---|
154 | 162 | |
---|
155 | 163 | static void uart_port_dtr_rts(struct uart_port *uport, int raise) |
---|
156 | 164 | { |
---|
157 | | - int rs485_on = uport->rs485_config && |
---|
158 | | - (uport->rs485.flags & SER_RS485_ENABLED); |
---|
159 | | - int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); |
---|
160 | | - |
---|
161 | | - if (raise) { |
---|
162 | | - if (rs485_on && RTS_after_send) { |
---|
163 | | - uart_set_mctrl(uport, TIOCM_DTR); |
---|
164 | | - uart_clear_mctrl(uport, TIOCM_RTS); |
---|
165 | | - } else { |
---|
166 | | - uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
---|
167 | | - } |
---|
168 | | - } else { |
---|
169 | | - unsigned int clear = TIOCM_DTR; |
---|
170 | | - |
---|
171 | | - clear |= (!rs485_on || RTS_after_send) ? TIOCM_RTS : 0; |
---|
172 | | - uart_clear_mctrl(uport, clear); |
---|
173 | | - } |
---|
| 165 | + if (raise) |
---|
| 166 | + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
---|
| 167 | + else |
---|
| 168 | + uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
---|
174 | 169 | } |
---|
175 | 170 | |
---|
176 | 171 | /* |
---|
.. | .. |
---|
667 | 662 | } |
---|
668 | 663 | |
---|
669 | 664 | /* |
---|
| 665 | + * This function performs low-level write of high-priority XON/XOFF |
---|
| 666 | + * character and accounting for it. |
---|
| 667 | + * |
---|
| 668 | + * Requires uart_port to implement .serial_out(). |
---|
| 669 | + */ |
---|
| 670 | +void uart_xchar_out(struct uart_port *uport, int offset) |
---|
| 671 | +{ |
---|
| 672 | + serial_port_out(uport, offset, uport->x_char); |
---|
| 673 | + uport->icount.tx++; |
---|
| 674 | + uport->x_char = 0; |
---|
| 675 | +} |
---|
| 676 | +EXPORT_SYMBOL_GPL(uart_xchar_out); |
---|
| 677 | + |
---|
| 678 | +/* |
---|
670 | 679 | * This function is used to send a high-priority XON/XOFF character to |
---|
671 | 680 | * the device |
---|
672 | 681 | */ |
---|
.. | .. |
---|
792 | 801 | return ret; |
---|
793 | 802 | } |
---|
794 | 803 | |
---|
795 | | -static int uart_get_info_user(struct tty_port *port, |
---|
796 | | - struct serial_struct __user *retinfo) |
---|
| 804 | +static int uart_get_info_user(struct tty_struct *tty, |
---|
| 805 | + struct serial_struct *ss) |
---|
797 | 806 | { |
---|
798 | | - struct serial_struct tmp; |
---|
| 807 | + struct uart_state *state = tty->driver_data; |
---|
| 808 | + struct tty_port *port = &state->port; |
---|
799 | 809 | |
---|
800 | | - if (uart_get_info(port, &tmp) < 0) |
---|
801 | | - return -EIO; |
---|
802 | | - |
---|
803 | | - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
---|
804 | | - return -EFAULT; |
---|
805 | | - return 0; |
---|
| 810 | + return uart_get_info(port, ss) < 0 ? -EIO : 0; |
---|
806 | 811 | } |
---|
807 | 812 | |
---|
808 | 813 | static int uart_set_info(struct tty_struct *tty, struct tty_port *port, |
---|
.. | .. |
---|
864 | 869 | (new_flags & UPF_USR_MASK)); |
---|
865 | 870 | uport->custom_divisor = new_info->custom_divisor; |
---|
866 | 871 | goto check_and_exit; |
---|
| 872 | + } |
---|
| 873 | + |
---|
| 874 | + if (change_irq || change_port) { |
---|
| 875 | + retval = security_locked_down(LOCKDOWN_TIOCSSERIAL); |
---|
| 876 | + if (retval) |
---|
| 877 | + goto exit; |
---|
867 | 878 | } |
---|
868 | 879 | |
---|
869 | 880 | /* |
---|
.. | .. |
---|
1004 | 1015 | return retval; |
---|
1005 | 1016 | } |
---|
1006 | 1017 | |
---|
1007 | | -static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, |
---|
1008 | | - struct serial_struct __user *newinfo) |
---|
| 1018 | +static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss) |
---|
1009 | 1019 | { |
---|
1010 | | - struct serial_struct new_serial; |
---|
| 1020 | + struct uart_state *state = tty->driver_data; |
---|
1011 | 1021 | struct tty_port *port = &state->port; |
---|
1012 | 1022 | int retval; |
---|
1013 | 1023 | |
---|
1014 | | - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
---|
1015 | | - return -EFAULT; |
---|
1016 | | - |
---|
| 1024 | + down_write(&tty->termios_rwsem); |
---|
1017 | 1025 | /* |
---|
1018 | 1026 | * This semaphore protects port->count. It is also |
---|
1019 | 1027 | * very useful to prevent opens. Also, take the |
---|
.. | .. |
---|
1022 | 1030 | * under us. |
---|
1023 | 1031 | */ |
---|
1024 | 1032 | mutex_lock(&port->mutex); |
---|
1025 | | - retval = uart_set_info(tty, port, state, &new_serial); |
---|
| 1033 | + retval = uart_set_info(tty, port, state, ss); |
---|
1026 | 1034 | mutex_unlock(&port->mutex); |
---|
| 1035 | + up_write(&tty->termios_rwsem); |
---|
1027 | 1036 | return retval; |
---|
1028 | 1037 | } |
---|
1029 | 1038 | |
---|
.. | .. |
---|
1120 | 1129 | return ret; |
---|
1121 | 1130 | } |
---|
1122 | 1131 | |
---|
1123 | | -static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) |
---|
| 1132 | +static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state) |
---|
1124 | 1133 | { |
---|
1125 | 1134 | struct tty_port *port = &state->port; |
---|
1126 | 1135 | struct uart_port *uport; |
---|
.. | .. |
---|
1305 | 1314 | unsigned long flags; |
---|
1306 | 1315 | |
---|
1307 | 1316 | if (!port->rs485_config) |
---|
1308 | | - return -ENOIOCTLCMD; |
---|
| 1317 | + return -ENOTTY; |
---|
1309 | 1318 | |
---|
1310 | 1319 | if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) |
---|
1311 | 1320 | return -EFAULT; |
---|
1312 | 1321 | |
---|
| 1322 | + /* pick sane settings if the user hasn't */ |
---|
| 1323 | + if (!(rs485.flags & SER_RS485_RTS_ON_SEND) == |
---|
| 1324 | + !(rs485.flags & SER_RS485_RTS_AFTER_SEND)) { |
---|
| 1325 | + dev_warn_ratelimited(port->dev, |
---|
| 1326 | + "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", |
---|
| 1327 | + port->name, port->line); |
---|
| 1328 | + rs485.flags |= SER_RS485_RTS_ON_SEND; |
---|
| 1329 | + rs485.flags &= ~SER_RS485_RTS_AFTER_SEND; |
---|
| 1330 | + } |
---|
| 1331 | + |
---|
| 1332 | + if (rs485.delay_rts_before_send > RS485_MAX_RTS_DELAY) { |
---|
| 1333 | + rs485.delay_rts_before_send = RS485_MAX_RTS_DELAY; |
---|
| 1334 | + dev_warn_ratelimited(port->dev, |
---|
| 1335 | + "%s (%d): RTS delay before sending clamped to %u ms\n", |
---|
| 1336 | + port->name, port->line, rs485.delay_rts_before_send); |
---|
| 1337 | + } |
---|
| 1338 | + |
---|
| 1339 | + if (rs485.delay_rts_after_send > RS485_MAX_RTS_DELAY) { |
---|
| 1340 | + rs485.delay_rts_after_send = RS485_MAX_RTS_DELAY; |
---|
| 1341 | + dev_warn_ratelimited(port->dev, |
---|
| 1342 | + "%s (%d): RTS delay after sending clamped to %u ms\n", |
---|
| 1343 | + port->name, port->line, rs485.delay_rts_after_send); |
---|
| 1344 | + } |
---|
| 1345 | + /* Return clean padding area to userspace */ |
---|
| 1346 | + memset(rs485.padding, 0, sizeof(rs485.padding)); |
---|
| 1347 | + |
---|
1313 | 1348 | spin_lock_irqsave(&port->lock, flags); |
---|
1314 | 1349 | ret = port->rs485_config(port, &rs485); |
---|
| 1350 | + if (!ret) { |
---|
| 1351 | + port->rs485 = rs485; |
---|
| 1352 | + |
---|
| 1353 | + /* Reset RTS and other mctrl lines when disabling RS485 */ |
---|
| 1354 | + if (!(rs485.flags & SER_RS485_ENABLED)) |
---|
| 1355 | + port->ops->set_mctrl(port, port->mctrl); |
---|
| 1356 | + } |
---|
1315 | 1357 | spin_unlock_irqrestore(&port->lock, flags); |
---|
1316 | 1358 | if (ret) |
---|
1317 | 1359 | return ret; |
---|
1318 | 1360 | |
---|
1319 | 1361 | if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485))) |
---|
| 1362 | + return -EFAULT; |
---|
| 1363 | + |
---|
| 1364 | + return 0; |
---|
| 1365 | +} |
---|
| 1366 | + |
---|
| 1367 | +static int uart_get_iso7816_config(struct uart_port *port, |
---|
| 1368 | + struct serial_iso7816 __user *iso7816) |
---|
| 1369 | +{ |
---|
| 1370 | + unsigned long flags; |
---|
| 1371 | + struct serial_iso7816 aux; |
---|
| 1372 | + |
---|
| 1373 | + if (!port->iso7816_config) |
---|
| 1374 | + return -ENOTTY; |
---|
| 1375 | + |
---|
| 1376 | + spin_lock_irqsave(&port->lock, flags); |
---|
| 1377 | + aux = port->iso7816; |
---|
| 1378 | + spin_unlock_irqrestore(&port->lock, flags); |
---|
| 1379 | + |
---|
| 1380 | + if (copy_to_user(iso7816, &aux, sizeof(aux))) |
---|
| 1381 | + return -EFAULT; |
---|
| 1382 | + |
---|
| 1383 | + return 0; |
---|
| 1384 | +} |
---|
| 1385 | + |
---|
| 1386 | +static int uart_set_iso7816_config(struct uart_port *port, |
---|
| 1387 | + struct serial_iso7816 __user *iso7816_user) |
---|
| 1388 | +{ |
---|
| 1389 | + struct serial_iso7816 iso7816; |
---|
| 1390 | + int i, ret; |
---|
| 1391 | + unsigned long flags; |
---|
| 1392 | + |
---|
| 1393 | + if (!port->iso7816_config) |
---|
| 1394 | + return -ENOTTY; |
---|
| 1395 | + |
---|
| 1396 | + if (copy_from_user(&iso7816, iso7816_user, sizeof(*iso7816_user))) |
---|
| 1397 | + return -EFAULT; |
---|
| 1398 | + |
---|
| 1399 | + /* |
---|
| 1400 | + * There are 5 words reserved for future use. Check that userspace |
---|
| 1401 | + * doesn't put stuff in there to prevent breakages in the future. |
---|
| 1402 | + */ |
---|
| 1403 | + for (i = 0; i < 5; i++) |
---|
| 1404 | + if (iso7816.reserved[i]) |
---|
| 1405 | + return -EINVAL; |
---|
| 1406 | + |
---|
| 1407 | + spin_lock_irqsave(&port->lock, flags); |
---|
| 1408 | + ret = port->iso7816_config(port, &iso7816); |
---|
| 1409 | + spin_unlock_irqrestore(&port->lock, flags); |
---|
| 1410 | + if (ret) |
---|
| 1411 | + return ret; |
---|
| 1412 | + |
---|
| 1413 | + if (copy_to_user(iso7816_user, &port->iso7816, sizeof(port->iso7816))) |
---|
1320 | 1414 | return -EFAULT; |
---|
1321 | 1415 | |
---|
1322 | 1416 | return 0; |
---|
.. | .. |
---|
1339 | 1433 | * These ioctls don't rely on the hardware to be present. |
---|
1340 | 1434 | */ |
---|
1341 | 1435 | switch (cmd) { |
---|
1342 | | - case TIOCGSERIAL: |
---|
1343 | | - ret = uart_get_info_user(port, uarg); |
---|
1344 | | - break; |
---|
1345 | | - |
---|
1346 | | - case TIOCSSERIAL: |
---|
1347 | | - down_write(&tty->termios_rwsem); |
---|
1348 | | - ret = uart_set_info_user(tty, state, uarg); |
---|
1349 | | - up_write(&tty->termios_rwsem); |
---|
1350 | | - break; |
---|
1351 | | - |
---|
1352 | 1436 | case TIOCSERCONFIG: |
---|
1353 | 1437 | down_write(&tty->termios_rwsem); |
---|
1354 | 1438 | ret = uart_do_autoconfig(tty, state); |
---|
1355 | 1439 | up_write(&tty->termios_rwsem); |
---|
1356 | | - break; |
---|
1357 | | - |
---|
1358 | | - case TIOCSERGWILD: /* obsolete */ |
---|
1359 | | - case TIOCSERSWILD: /* obsolete */ |
---|
1360 | | - ret = 0; |
---|
1361 | 1440 | break; |
---|
1362 | 1441 | } |
---|
1363 | 1442 | |
---|
.. | .. |
---|
1405 | 1484 | |
---|
1406 | 1485 | case TIOCSRS485: |
---|
1407 | 1486 | ret = uart_set_rs485_config(uport, uarg); |
---|
| 1487 | + break; |
---|
| 1488 | + |
---|
| 1489 | + case TIOCSISO7816: |
---|
| 1490 | + ret = uart_set_iso7816_config(state->uart_port, uarg); |
---|
| 1491 | + break; |
---|
| 1492 | + |
---|
| 1493 | + case TIOCGISO7816: |
---|
| 1494 | + ret = uart_get_iso7816_config(state->uart_port, uarg); |
---|
1408 | 1495 | break; |
---|
1409 | 1496 | default: |
---|
1410 | 1497 | if (uport->ops->ioctl) |
---|
.. | .. |
---|
1473 | 1560 | } |
---|
1474 | 1561 | |
---|
1475 | 1562 | uart_change_speed(tty, state, old_termios); |
---|
1476 | | - /* reload cflag from termios; port driver may have overriden flags */ |
---|
| 1563 | + /* reload cflag from termios; port driver may have overridden flags */ |
---|
1477 | 1564 | cflag = tty->termios.c_cflag; |
---|
1478 | 1565 | |
---|
1479 | 1566 | /* Handle transition to B0 status */ |
---|
.. | .. |
---|
1482 | 1569 | /* Handle transition away from B0 status */ |
---|
1483 | 1570 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
---|
1484 | 1571 | unsigned int mask = TIOCM_DTR; |
---|
| 1572 | + |
---|
1485 | 1573 | if (!(cflag & CRTSCTS) || !tty_throttled(tty)) |
---|
1486 | 1574 | mask |= TIOCM_RTS; |
---|
1487 | 1575 | uart_set_mctrl(uport, mask); |
---|
.. | .. |
---|
1879 | 1967 | } |
---|
1880 | 1968 | #endif |
---|
1881 | 1969 | |
---|
| 1970 | +static void uart_port_spin_lock_init(struct uart_port *port) |
---|
| 1971 | +{ |
---|
| 1972 | + spin_lock_init(&port->lock); |
---|
| 1973 | + lockdep_set_class(&port->lock, &port_lock_key); |
---|
| 1974 | +} |
---|
| 1975 | + |
---|
1882 | 1976 | #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) |
---|
1883 | 1977 | /** |
---|
1884 | 1978 | * uart_console_write - write a console message to a serial port |
---|
.. | .. |
---|
1935 | 2029 | * console=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options> |
---|
1936 | 2030 | * |
---|
1937 | 2031 | * The optional form |
---|
| 2032 | + * |
---|
1938 | 2033 | * earlycon=<name>,0x<addr>,<options> |
---|
1939 | 2034 | * console=<name>,0x<addr>,<options> |
---|
| 2035 | + * |
---|
1940 | 2036 | * is also accepted; the returned @iotype will be UPIO_MEM. |
---|
1941 | 2037 | * |
---|
1942 | 2038 | * Returns 0 on success or -EINVAL on failure |
---|
.. | .. |
---|
2030 | 2126 | static struct ktermios dummy; |
---|
2031 | 2127 | |
---|
2032 | 2128 | /* |
---|
2033 | | - * Ensure that the serial console lock is initialised |
---|
2034 | | - * early. |
---|
2035 | | - * If this port is a console, then the spinlock is already |
---|
2036 | | - * initialised. |
---|
| 2129 | + * Ensure that the serial-console lock is initialised early. |
---|
| 2130 | + * |
---|
| 2131 | + * Note that the console-enabled check is needed because of kgdboc, |
---|
| 2132 | + * which can end up calling uart_set_options() for an already enabled |
---|
| 2133 | + * console via tty_find_polling_driver() and uart_poll_init(). |
---|
2037 | 2134 | */ |
---|
2038 | | - if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) { |
---|
2039 | | - spin_lock_init(&port->lock); |
---|
2040 | | - lockdep_set_class(&port->lock, &port_lock_key); |
---|
2041 | | - } |
---|
| 2135 | + if (!uart_console_enabled(port) && !port->console_reinit) |
---|
| 2136 | + uart_port_spin_lock_init(port); |
---|
2042 | 2137 | |
---|
2043 | 2138 | memset(&termios, 0, sizeof(struct ktermios)); |
---|
2044 | 2139 | |
---|
.. | .. |
---|
2053 | 2148 | switch (parity) { |
---|
2054 | 2149 | case 'o': case 'O': |
---|
2055 | 2150 | termios.c_cflag |= PARODD; |
---|
2056 | | - /*fall through*/ |
---|
| 2151 | + fallthrough; |
---|
2057 | 2152 | case 'e': case 'E': |
---|
2058 | 2153 | termios.c_cflag |= PARENB; |
---|
2059 | 2154 | break; |
---|
.. | .. |
---|
2149 | 2244 | |
---|
2150 | 2245 | spin_lock_irq(&uport->lock); |
---|
2151 | 2246 | ops->stop_tx(uport); |
---|
2152 | | - ops->set_mctrl(uport, 0); |
---|
| 2247 | + if (!(uport->rs485.flags & SER_RS485_ENABLED)) |
---|
| 2248 | + ops->set_mctrl(uport, 0); |
---|
2153 | 2249 | ops->stop_rx(uport); |
---|
2154 | 2250 | spin_unlock_irq(&uport->lock); |
---|
2155 | 2251 | |
---|
.. | .. |
---|
2228 | 2324 | |
---|
2229 | 2325 | uart_change_pm(state, UART_PM_STATE_ON); |
---|
2230 | 2326 | spin_lock_irq(&uport->lock); |
---|
2231 | | - ops->set_mctrl(uport, 0); |
---|
| 2327 | + if (!(uport->rs485.flags & SER_RS485_ENABLED)) |
---|
| 2328 | + ops->set_mctrl(uport, 0); |
---|
2232 | 2329 | spin_unlock_irq(&uport->lock); |
---|
2233 | 2330 | if (console_suspend_enabled || !uart_console(uport)) { |
---|
2234 | 2331 | /* Protected by port mutex for now */ |
---|
2235 | 2332 | struct tty_struct *tty = port->tty; |
---|
| 2333 | + |
---|
2236 | 2334 | ret = ops->startup(uport); |
---|
2237 | 2335 | if (ret == 0) { |
---|
2238 | 2336 | if (tty) |
---|
2239 | 2337 | uart_change_speed(tty, state, NULL); |
---|
2240 | 2338 | spin_lock_irq(&uport->lock); |
---|
2241 | | - ops->set_mctrl(uport, uport->mctrl); |
---|
| 2339 | + if (!(uport->rs485.flags & SER_RS485_ENABLED)) |
---|
| 2340 | + ops->set_mctrl(uport, uport->mctrl); |
---|
| 2341 | + else |
---|
| 2342 | + uport->rs485_config(uport, &uport->rs485); |
---|
2242 | 2343 | ops->start_tx(uport); |
---|
2243 | 2344 | spin_unlock_irq(&uport->lock); |
---|
2244 | 2345 | tty_port_set_initialized(port, 1); |
---|
.. | .. |
---|
2336 | 2437 | */ |
---|
2337 | 2438 | spin_lock_irqsave(&port->lock, flags); |
---|
2338 | 2439 | port->mctrl &= TIOCM_DTR; |
---|
2339 | | - port->ops->set_mctrl(port, port->mctrl); |
---|
| 2440 | + if (!(port->rs485.flags & SER_RS485_ENABLED)) |
---|
| 2441 | + port->ops->set_mctrl(port, port->mctrl); |
---|
| 2442 | + else |
---|
| 2443 | + port->rs485_config(port, &port->rs485); |
---|
2340 | 2444 | spin_unlock_irqrestore(&port->lock, flags); |
---|
2341 | 2445 | |
---|
2342 | 2446 | /* |
---|
.. | .. |
---|
2456 | 2560 | #endif |
---|
2457 | 2561 | .tiocmget = uart_tiocmget, |
---|
2458 | 2562 | .tiocmset = uart_tiocmset, |
---|
| 2563 | + .set_serial = uart_set_info_user, |
---|
| 2564 | + .get_serial = uart_get_info_user, |
---|
2459 | 2565 | .get_icount = uart_get_icount, |
---|
2460 | 2566 | #ifdef CONFIG_CONSOLE_POLL |
---|
2461 | 2567 | .poll_init = uart_poll_init, |
---|
.. | .. |
---|
2487 | 2593 | int uart_register_driver(struct uart_driver *drv) |
---|
2488 | 2594 | { |
---|
2489 | 2595 | struct tty_driver *normal; |
---|
2490 | | - int i, retval; |
---|
| 2596 | + int i, retval = -ENOMEM; |
---|
2491 | 2597 | |
---|
2492 | 2598 | BUG_ON(drv->state); |
---|
2493 | 2599 | |
---|
.. | .. |
---|
2539 | 2645 | out_kfree: |
---|
2540 | 2646 | kfree(drv->state); |
---|
2541 | 2647 | out: |
---|
2542 | | - return -ENOMEM; |
---|
| 2648 | + return retval; |
---|
2543 | 2649 | } |
---|
2544 | 2650 | |
---|
2545 | 2651 | /** |
---|
.. | .. |
---|
2573 | 2679 | } |
---|
2574 | 2680 | EXPORT_SYMBOL_GPL(uart_console_device); |
---|
2575 | 2681 | |
---|
2576 | | -static ssize_t uart_get_attr_uartclk(struct device *dev, |
---|
| 2682 | +static ssize_t uartclk_show(struct device *dev, |
---|
2577 | 2683 | struct device_attribute *attr, char *buf) |
---|
2578 | 2684 | { |
---|
2579 | 2685 | struct serial_struct tmp; |
---|
2580 | 2686 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2581 | 2687 | |
---|
2582 | 2688 | uart_get_info(port, &tmp); |
---|
2583 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); |
---|
| 2689 | + return sprintf(buf, "%d\n", tmp.baud_base * 16); |
---|
2584 | 2690 | } |
---|
2585 | 2691 | |
---|
2586 | | -static ssize_t uart_get_attr_type(struct device *dev, |
---|
| 2692 | +static ssize_t type_show(struct device *dev, |
---|
2587 | 2693 | struct device_attribute *attr, char *buf) |
---|
2588 | 2694 | { |
---|
2589 | 2695 | struct serial_struct tmp; |
---|
2590 | 2696 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2591 | 2697 | |
---|
2592 | 2698 | uart_get_info(port, &tmp); |
---|
2593 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type); |
---|
| 2699 | + return sprintf(buf, "%d\n", tmp.type); |
---|
2594 | 2700 | } |
---|
2595 | | -static ssize_t uart_get_attr_line(struct device *dev, |
---|
| 2701 | + |
---|
| 2702 | +static ssize_t line_show(struct device *dev, |
---|
2596 | 2703 | struct device_attribute *attr, char *buf) |
---|
2597 | 2704 | { |
---|
2598 | 2705 | struct serial_struct tmp; |
---|
2599 | 2706 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2600 | 2707 | |
---|
2601 | 2708 | uart_get_info(port, &tmp); |
---|
2602 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line); |
---|
| 2709 | + return sprintf(buf, "%d\n", tmp.line); |
---|
2603 | 2710 | } |
---|
2604 | 2711 | |
---|
2605 | | -static ssize_t uart_get_attr_port(struct device *dev, |
---|
| 2712 | +static ssize_t port_show(struct device *dev, |
---|
2606 | 2713 | struct device_attribute *attr, char *buf) |
---|
2607 | 2714 | { |
---|
2608 | 2715 | struct serial_struct tmp; |
---|
.. | .. |
---|
2613 | 2720 | ioaddr = tmp.port; |
---|
2614 | 2721 | if (HIGH_BITS_OFFSET) |
---|
2615 | 2722 | ioaddr |= (unsigned long)tmp.port_high << HIGH_BITS_OFFSET; |
---|
2616 | | - return snprintf(buf, PAGE_SIZE, "0x%lX\n", ioaddr); |
---|
| 2723 | + return sprintf(buf, "0x%lX\n", ioaddr); |
---|
2617 | 2724 | } |
---|
2618 | 2725 | |
---|
2619 | | -static ssize_t uart_get_attr_irq(struct device *dev, |
---|
| 2726 | +static ssize_t irq_show(struct device *dev, |
---|
2620 | 2727 | struct device_attribute *attr, char *buf) |
---|
2621 | 2728 | { |
---|
2622 | 2729 | struct serial_struct tmp; |
---|
2623 | 2730 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2624 | 2731 | |
---|
2625 | 2732 | uart_get_info(port, &tmp); |
---|
2626 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq); |
---|
| 2733 | + return sprintf(buf, "%d\n", tmp.irq); |
---|
2627 | 2734 | } |
---|
2628 | 2735 | |
---|
2629 | | -static ssize_t uart_get_attr_flags(struct device *dev, |
---|
| 2736 | +static ssize_t flags_show(struct device *dev, |
---|
2630 | 2737 | struct device_attribute *attr, char *buf) |
---|
2631 | 2738 | { |
---|
2632 | 2739 | struct serial_struct tmp; |
---|
2633 | 2740 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2634 | 2741 | |
---|
2635 | 2742 | uart_get_info(port, &tmp); |
---|
2636 | | - return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags); |
---|
| 2743 | + return sprintf(buf, "0x%X\n", tmp.flags); |
---|
2637 | 2744 | } |
---|
2638 | 2745 | |
---|
2639 | | -static ssize_t uart_get_attr_xmit_fifo_size(struct device *dev, |
---|
| 2746 | +static ssize_t xmit_fifo_size_show(struct device *dev, |
---|
2640 | 2747 | struct device_attribute *attr, char *buf) |
---|
2641 | 2748 | { |
---|
2642 | 2749 | struct serial_struct tmp; |
---|
2643 | 2750 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2644 | 2751 | |
---|
2645 | 2752 | uart_get_info(port, &tmp); |
---|
2646 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size); |
---|
| 2753 | + return sprintf(buf, "%d\n", tmp.xmit_fifo_size); |
---|
2647 | 2754 | } |
---|
2648 | 2755 | |
---|
2649 | | - |
---|
2650 | | -static ssize_t uart_get_attr_close_delay(struct device *dev, |
---|
| 2756 | +static ssize_t close_delay_show(struct device *dev, |
---|
2651 | 2757 | struct device_attribute *attr, char *buf) |
---|
2652 | 2758 | { |
---|
2653 | 2759 | struct serial_struct tmp; |
---|
2654 | 2760 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2655 | 2761 | |
---|
2656 | 2762 | uart_get_info(port, &tmp); |
---|
2657 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay); |
---|
| 2763 | + return sprintf(buf, "%d\n", tmp.close_delay); |
---|
2658 | 2764 | } |
---|
2659 | 2765 | |
---|
2660 | | - |
---|
2661 | | -static ssize_t uart_get_attr_closing_wait(struct device *dev, |
---|
| 2766 | +static ssize_t closing_wait_show(struct device *dev, |
---|
2662 | 2767 | struct device_attribute *attr, char *buf) |
---|
2663 | 2768 | { |
---|
2664 | 2769 | struct serial_struct tmp; |
---|
2665 | 2770 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2666 | 2771 | |
---|
2667 | 2772 | uart_get_info(port, &tmp); |
---|
2668 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait); |
---|
| 2773 | + return sprintf(buf, "%d\n", tmp.closing_wait); |
---|
2669 | 2774 | } |
---|
2670 | 2775 | |
---|
2671 | | -static ssize_t uart_get_attr_custom_divisor(struct device *dev, |
---|
| 2776 | +static ssize_t custom_divisor_show(struct device *dev, |
---|
2672 | 2777 | struct device_attribute *attr, char *buf) |
---|
2673 | 2778 | { |
---|
2674 | 2779 | struct serial_struct tmp; |
---|
2675 | 2780 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2676 | 2781 | |
---|
2677 | 2782 | uart_get_info(port, &tmp); |
---|
2678 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor); |
---|
| 2783 | + return sprintf(buf, "%d\n", tmp.custom_divisor); |
---|
2679 | 2784 | } |
---|
2680 | 2785 | |
---|
2681 | | -static ssize_t uart_get_attr_io_type(struct device *dev, |
---|
| 2786 | +static ssize_t io_type_show(struct device *dev, |
---|
2682 | 2787 | struct device_attribute *attr, char *buf) |
---|
2683 | 2788 | { |
---|
2684 | 2789 | struct serial_struct tmp; |
---|
2685 | 2790 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2686 | 2791 | |
---|
2687 | 2792 | uart_get_info(port, &tmp); |
---|
2688 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type); |
---|
| 2793 | + return sprintf(buf, "%d\n", tmp.io_type); |
---|
2689 | 2794 | } |
---|
2690 | 2795 | |
---|
2691 | | -static ssize_t uart_get_attr_iomem_base(struct device *dev, |
---|
| 2796 | +static ssize_t iomem_base_show(struct device *dev, |
---|
2692 | 2797 | struct device_attribute *attr, char *buf) |
---|
2693 | 2798 | { |
---|
2694 | 2799 | struct serial_struct tmp; |
---|
2695 | 2800 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2696 | 2801 | |
---|
2697 | 2802 | uart_get_info(port, &tmp); |
---|
2698 | | - return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base); |
---|
| 2803 | + return sprintf(buf, "0x%lX\n", (unsigned long)tmp.iomem_base); |
---|
2699 | 2804 | } |
---|
2700 | 2805 | |
---|
2701 | | -static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, |
---|
| 2806 | +static ssize_t iomem_reg_shift_show(struct device *dev, |
---|
2702 | 2807 | struct device_attribute *attr, char *buf) |
---|
2703 | 2808 | { |
---|
2704 | 2809 | struct serial_struct tmp; |
---|
2705 | 2810 | struct tty_port *port = dev_get_drvdata(dev); |
---|
2706 | 2811 | |
---|
2707 | 2812 | uart_get_info(port, &tmp); |
---|
2708 | | - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); |
---|
| 2813 | + return sprintf(buf, "%d\n", tmp.iomem_reg_shift); |
---|
2709 | 2814 | } |
---|
2710 | 2815 | |
---|
2711 | | -static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL); |
---|
2712 | | -static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL); |
---|
2713 | | -static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); |
---|
2714 | | -static DEVICE_ATTR(irq, S_IRUSR | S_IRGRP, uart_get_attr_irq, NULL); |
---|
2715 | | -static DEVICE_ATTR(flags, S_IRUSR | S_IRGRP, uart_get_attr_flags, NULL); |
---|
2716 | | -static DEVICE_ATTR(xmit_fifo_size, S_IRUSR | S_IRGRP, uart_get_attr_xmit_fifo_size, NULL); |
---|
2717 | | -static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); |
---|
2718 | | -static DEVICE_ATTR(close_delay, S_IRUSR | S_IRGRP, uart_get_attr_close_delay, NULL); |
---|
2719 | | -static DEVICE_ATTR(closing_wait, S_IRUSR | S_IRGRP, uart_get_attr_closing_wait, NULL); |
---|
2720 | | -static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divisor, NULL); |
---|
2721 | | -static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL); |
---|
2722 | | -static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL); |
---|
2723 | | -static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL); |
---|
| 2816 | +static ssize_t console_show(struct device *dev, |
---|
| 2817 | + struct device_attribute *attr, char *buf) |
---|
| 2818 | +{ |
---|
| 2819 | + struct tty_port *port = dev_get_drvdata(dev); |
---|
| 2820 | + struct uart_state *state = container_of(port, struct uart_state, port); |
---|
| 2821 | + struct uart_port *uport; |
---|
| 2822 | + bool console = false; |
---|
| 2823 | + |
---|
| 2824 | + mutex_lock(&port->mutex); |
---|
| 2825 | + uport = uart_port_check(state); |
---|
| 2826 | + if (uport) |
---|
| 2827 | + console = uart_console_enabled(uport); |
---|
| 2828 | + mutex_unlock(&port->mutex); |
---|
| 2829 | + |
---|
| 2830 | + return sprintf(buf, "%c\n", console ? 'Y' : 'N'); |
---|
| 2831 | +} |
---|
| 2832 | + |
---|
| 2833 | +static ssize_t console_store(struct device *dev, |
---|
| 2834 | + struct device_attribute *attr, const char *buf, size_t count) |
---|
| 2835 | +{ |
---|
| 2836 | + struct tty_port *port = dev_get_drvdata(dev); |
---|
| 2837 | + struct uart_state *state = container_of(port, struct uart_state, port); |
---|
| 2838 | + struct uart_port *uport; |
---|
| 2839 | + bool oldconsole, newconsole; |
---|
| 2840 | + int ret; |
---|
| 2841 | + |
---|
| 2842 | + ret = kstrtobool(buf, &newconsole); |
---|
| 2843 | + if (ret) |
---|
| 2844 | + return ret; |
---|
| 2845 | + |
---|
| 2846 | + mutex_lock(&port->mutex); |
---|
| 2847 | + uport = uart_port_check(state); |
---|
| 2848 | + if (uport) { |
---|
| 2849 | + oldconsole = uart_console_enabled(uport); |
---|
| 2850 | + if (oldconsole && !newconsole) { |
---|
| 2851 | + ret = unregister_console(uport->cons); |
---|
| 2852 | + } else if (!oldconsole && newconsole) { |
---|
| 2853 | + if (uart_console(uport)) { |
---|
| 2854 | + uport->console_reinit = 1; |
---|
| 2855 | + register_console(uport->cons); |
---|
| 2856 | + } else { |
---|
| 2857 | + ret = -ENOENT; |
---|
| 2858 | + } |
---|
| 2859 | + } |
---|
| 2860 | + } else { |
---|
| 2861 | + ret = -ENXIO; |
---|
| 2862 | + } |
---|
| 2863 | + mutex_unlock(&port->mutex); |
---|
| 2864 | + |
---|
| 2865 | + return ret < 0 ? ret : count; |
---|
| 2866 | +} |
---|
| 2867 | + |
---|
| 2868 | +static DEVICE_ATTR_RO(uartclk); |
---|
| 2869 | +static DEVICE_ATTR_RO(type); |
---|
| 2870 | +static DEVICE_ATTR_RO(line); |
---|
| 2871 | +static DEVICE_ATTR_RO(port); |
---|
| 2872 | +static DEVICE_ATTR_RO(irq); |
---|
| 2873 | +static DEVICE_ATTR_RO(flags); |
---|
| 2874 | +static DEVICE_ATTR_RO(xmit_fifo_size); |
---|
| 2875 | +static DEVICE_ATTR_RO(close_delay); |
---|
| 2876 | +static DEVICE_ATTR_RO(closing_wait); |
---|
| 2877 | +static DEVICE_ATTR_RO(custom_divisor); |
---|
| 2878 | +static DEVICE_ATTR_RO(io_type); |
---|
| 2879 | +static DEVICE_ATTR_RO(iomem_base); |
---|
| 2880 | +static DEVICE_ATTR_RO(iomem_reg_shift); |
---|
| 2881 | +static DEVICE_ATTR_RW(console); |
---|
2724 | 2882 | |
---|
2725 | 2883 | static struct attribute *tty_dev_attrs[] = { |
---|
| 2884 | + &dev_attr_uartclk.attr, |
---|
2726 | 2885 | &dev_attr_type.attr, |
---|
2727 | 2886 | &dev_attr_line.attr, |
---|
2728 | 2887 | &dev_attr_port.attr, |
---|
2729 | 2888 | &dev_attr_irq.attr, |
---|
2730 | 2889 | &dev_attr_flags.attr, |
---|
2731 | 2890 | &dev_attr_xmit_fifo_size.attr, |
---|
2732 | | - &dev_attr_uartclk.attr, |
---|
2733 | 2891 | &dev_attr_close_delay.attr, |
---|
2734 | 2892 | &dev_attr_closing_wait.attr, |
---|
2735 | 2893 | &dev_attr_custom_divisor.attr, |
---|
2736 | 2894 | &dev_attr_io_type.attr, |
---|
2737 | 2895 | &dev_attr_iomem_base.attr, |
---|
2738 | 2896 | &dev_attr_iomem_reg_shift.attr, |
---|
2739 | | - NULL, |
---|
2740 | | - }; |
---|
| 2897 | + &dev_attr_console.attr, |
---|
| 2898 | + NULL |
---|
| 2899 | +}; |
---|
2741 | 2900 | |
---|
2742 | 2901 | static const struct attribute_group tty_dev_attr_group = { |
---|
2743 | 2902 | .attrs = tty_dev_attrs, |
---|
2744 | | - }; |
---|
| 2903 | +}; |
---|
2745 | 2904 | |
---|
2746 | 2905 | /** |
---|
2747 | 2906 | * uart_add_one_port - attach a driver-defined port structure |
---|
.. | .. |
---|
2793 | 2952 | } |
---|
2794 | 2953 | |
---|
2795 | 2954 | /* |
---|
2796 | | - * If this port is a console, then the spinlock is already |
---|
| 2955 | + * If this port is in use as a console then the spinlock is already |
---|
2797 | 2956 | * initialised. |
---|
2798 | 2957 | */ |
---|
2799 | | - if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) { |
---|
2800 | | - spin_lock_init(&uport->lock); |
---|
2801 | | - lockdep_set_class(&uport->lock, &port_lock_key); |
---|
2802 | | - } |
---|
| 2958 | + if (!uart_console_enabled(uport)) |
---|
| 2959 | + uart_port_spin_lock_init(uport); |
---|
| 2960 | + |
---|
2803 | 2961 | if (uport->cons && uport->dev) |
---|
2804 | 2962 | of_console_check(uport->dev->of_node, uport->cons->name, uport->line); |
---|
2805 | 2963 | |
---|
.. | .. |
---|
2828 | 2986 | */ |
---|
2829 | 2987 | tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver, |
---|
2830 | 2988 | uport->line, uport->dev, port, uport->tty_groups); |
---|
2831 | | - if (likely(!IS_ERR(tty_dev))) { |
---|
| 2989 | + if (!IS_ERR(tty_dev)) { |
---|
2832 | 2990 | device_set_wakeup_capable(tty_dev, 1); |
---|
2833 | 2991 | } else { |
---|
2834 | 2992 | dev_err(uport->dev, "Cannot register tty device on line %d\n", |
---|
.. | .. |
---|
3050 | 3208 | } |
---|
3051 | 3209 | EXPORT_SYMBOL_GPL(uart_insert_char); |
---|
3052 | 3210 | |
---|
| 3211 | +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL |
---|
| 3212 | +static const char sysrq_toggle_seq[] = CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE; |
---|
| 3213 | + |
---|
| 3214 | +static void uart_sysrq_on(struct work_struct *w) |
---|
| 3215 | +{ |
---|
| 3216 | + int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq); |
---|
| 3217 | + |
---|
| 3218 | + sysrq_toggle_support(1); |
---|
| 3219 | + pr_info("SysRq is enabled by magic sequence '%*pE' on serial\n", |
---|
| 3220 | + sysrq_toggle_seq_len, sysrq_toggle_seq); |
---|
| 3221 | +} |
---|
| 3222 | +static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on); |
---|
| 3223 | + |
---|
| 3224 | +/** |
---|
| 3225 | + * uart_try_toggle_sysrq - Enables SysRq from serial line |
---|
| 3226 | + * @port: uart_port structure where char(s) after BREAK met |
---|
| 3227 | + * @ch: new character in the sequence after received BREAK |
---|
| 3228 | + * |
---|
| 3229 | + * Enables magic SysRq when the required sequence is met on port |
---|
| 3230 | + * (see CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE). |
---|
| 3231 | + * |
---|
| 3232 | + * Returns false if @ch is out of enabling sequence and should be |
---|
| 3233 | + * handled some other way, true if @ch was consumed. |
---|
| 3234 | + */ |
---|
| 3235 | +bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) |
---|
| 3236 | +{ |
---|
| 3237 | + int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq); |
---|
| 3238 | + |
---|
| 3239 | + if (!sysrq_toggle_seq_len) |
---|
| 3240 | + return false; |
---|
| 3241 | + |
---|
| 3242 | + BUILD_BUG_ON(ARRAY_SIZE(sysrq_toggle_seq) >= U8_MAX); |
---|
| 3243 | + if (sysrq_toggle_seq[port->sysrq_seq] != ch) { |
---|
| 3244 | + port->sysrq_seq = 0; |
---|
| 3245 | + return false; |
---|
| 3246 | + } |
---|
| 3247 | + |
---|
| 3248 | + if (++port->sysrq_seq < sysrq_toggle_seq_len) { |
---|
| 3249 | + port->sysrq = jiffies + SYSRQ_TIMEOUT; |
---|
| 3250 | + return true; |
---|
| 3251 | + } |
---|
| 3252 | + |
---|
| 3253 | + schedule_work(&sysrq_enable_work); |
---|
| 3254 | + |
---|
| 3255 | + port->sysrq = 0; |
---|
| 3256 | + return true; |
---|
| 3257 | +} |
---|
| 3258 | +EXPORT_SYMBOL_GPL(uart_try_toggle_sysrq); |
---|
| 3259 | +#endif |
---|
| 3260 | + |
---|
3053 | 3261 | EXPORT_SYMBOL(uart_write_wakeup); |
---|
3054 | 3262 | EXPORT_SYMBOL(uart_register_driver); |
---|
3055 | 3263 | EXPORT_SYMBOL(uart_unregister_driver); |
---|
.. | .. |
---|
3060 | 3268 | |
---|
3061 | 3269 | /** |
---|
3062 | 3270 | * uart_get_rs485_mode() - retrieve rs485 properties for given uart |
---|
3063 | | - * @dev: uart device |
---|
3064 | | - * @rs485conf: output parameter |
---|
| 3271 | + * @port: uart device's target port |
---|
3065 | 3272 | * |
---|
3066 | 3273 | * This function implements the device tree binding described in |
---|
3067 | 3274 | * Documentation/devicetree/bindings/serial/rs485.txt. |
---|
3068 | 3275 | */ |
---|
3069 | | -void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf) |
---|
| 3276 | +int uart_get_rs485_mode(struct uart_port *port) |
---|
3070 | 3277 | { |
---|
| 3278 | + struct serial_rs485 *rs485conf = &port->rs485; |
---|
| 3279 | + struct device *dev = port->dev; |
---|
3071 | 3280 | u32 rs485_delay[2]; |
---|
3072 | 3281 | int ret; |
---|
3073 | 3282 | |
---|
.. | .. |
---|
3086 | 3295 | * to get to a defined state with the following properties: |
---|
3087 | 3296 | */ |
---|
3088 | 3297 | rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED | |
---|
| 3298 | + SER_RS485_TERMINATE_BUS | |
---|
3089 | 3299 | SER_RS485_RTS_AFTER_SEND); |
---|
3090 | 3300 | rs485conf->flags |= SER_RS485_RTS_ON_SEND; |
---|
3091 | 3301 | |
---|
.. | .. |
---|
3099 | 3309 | rs485conf->flags &= ~SER_RS485_RTS_ON_SEND; |
---|
3100 | 3310 | rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; |
---|
3101 | 3311 | } |
---|
| 3312 | + |
---|
| 3313 | + /* |
---|
| 3314 | + * Disabling termination by default is the safe choice: Else if many |
---|
| 3315 | + * bus participants enable it, no communication is possible at all. |
---|
| 3316 | + * Works fine for short cables and users may enable for longer cables. |
---|
| 3317 | + */ |
---|
| 3318 | + port->rs485_term_gpio = devm_gpiod_get_optional(dev, "rs485-term", |
---|
| 3319 | + GPIOD_OUT_LOW); |
---|
| 3320 | + if (IS_ERR(port->rs485_term_gpio)) { |
---|
| 3321 | + ret = PTR_ERR(port->rs485_term_gpio); |
---|
| 3322 | + port->rs485_term_gpio = NULL; |
---|
| 3323 | + return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n"); |
---|
| 3324 | + } |
---|
| 3325 | + |
---|
| 3326 | + return 0; |
---|
3102 | 3327 | } |
---|
3103 | 3328 | EXPORT_SYMBOL_GPL(uart_get_rs485_mode); |
---|
3104 | 3329 | |
---|