diff options
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 93 |
1 files changed, 35 insertions, 58 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 18c30cabe27f..435478a245d3 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #include <dt-bindings/gpio/gpio.h> | 47 | #include <dt-bindings/gpio/gpio.h> |
48 | 48 | ||
49 | #define OMAP_MAX_HSUART_PORTS 6 | 49 | #define OMAP_MAX_HSUART_PORTS 10 |
50 | 50 | ||
51 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) | 51 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) |
52 | 52 | ||
@@ -163,7 +163,6 @@ struct uart_omap_port { | |||
163 | u8 wakeups_enabled; | 163 | u8 wakeups_enabled; |
164 | u32 features; | 164 | u32 features; |
165 | 165 | ||
166 | struct serial_rs485 rs485; | ||
167 | int rts_gpio; | 166 | int rts_gpio; |
168 | 167 | ||
169 | struct pm_qos_request pm_qos_request; | 168 | struct pm_qos_request pm_qos_request; |
@@ -316,7 +315,7 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
316 | pm_runtime_get_sync(up->dev); | 315 | pm_runtime_get_sync(up->dev); |
317 | 316 | ||
318 | /* Handle RS-485 */ | 317 | /* Handle RS-485 */ |
319 | if (up->rs485.flags & SER_RS485_ENABLED) { | 318 | if (port->rs485.flags & SER_RS485_ENABLED) { |
320 | if (up->scr & OMAP_UART_SCR_TX_EMPTY) { | 319 | if (up->scr & OMAP_UART_SCR_TX_EMPTY) { |
321 | /* THR interrupt is fired when both TX FIFO and TX | 320 | /* THR interrupt is fired when both TX FIFO and TX |
322 | * shift register are empty. This means there's nothing | 321 | * shift register are empty. This means there's nothing |
@@ -327,10 +326,12 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
327 | */ | 326 | */ |
328 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; | 327 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
329 | serial_out(up, UART_OMAP_SCR, up->scr); | 328 | serial_out(up, UART_OMAP_SCR, up->scr); |
330 | res = (up->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? 1 : 0; | 329 | res = (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? |
330 | 1 : 0; | ||
331 | if (gpio_get_value(up->rts_gpio) != res) { | 331 | if (gpio_get_value(up->rts_gpio) != res) { |
332 | if (up->rs485.delay_rts_after_send > 0) | 332 | if (port->rs485.delay_rts_after_send > 0) |
333 | mdelay(up->rs485.delay_rts_after_send); | 333 | mdelay( |
334 | port->rs485.delay_rts_after_send); | ||
334 | gpio_set_value(up->rts_gpio, res); | 335 | gpio_set_value(up->rts_gpio, res); |
335 | } | 336 | } |
336 | } else { | 337 | } else { |
@@ -353,8 +354,8 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
353 | serial_out(up, UART_IER, up->ier); | 354 | serial_out(up, UART_IER, up->ier); |
354 | } | 355 | } |
355 | 356 | ||
356 | if ((up->rs485.flags & SER_RS485_ENABLED) && | 357 | if ((port->rs485.flags & SER_RS485_ENABLED) && |
357 | !(up->rs485.flags & SER_RS485_RX_DURING_TX)) { | 358 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { |
358 | /* | 359 | /* |
359 | * Empty the RX FIFO, we are not interested in anything | 360 | * Empty the RX FIFO, we are not interested in anything |
360 | * received during the half-duplex transmission. | 361 | * received during the half-duplex transmission. |
@@ -429,22 +430,22 @@ static void serial_omap_start_tx(struct uart_port *port) | |||
429 | pm_runtime_get_sync(up->dev); | 430 | pm_runtime_get_sync(up->dev); |
430 | 431 | ||
431 | /* Handle RS-485 */ | 432 | /* Handle RS-485 */ |
432 | if (up->rs485.flags & SER_RS485_ENABLED) { | 433 | if (port->rs485.flags & SER_RS485_ENABLED) { |
433 | /* Fire THR interrupts when FIFO is below trigger level */ | 434 | /* Fire THR interrupts when FIFO is below trigger level */ |
434 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; | 435 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
435 | serial_out(up, UART_OMAP_SCR, up->scr); | 436 | serial_out(up, UART_OMAP_SCR, up->scr); |
436 | 437 | ||
437 | /* if rts not already enabled */ | 438 | /* if rts not already enabled */ |
438 | res = (up->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; | 439 | res = (port->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; |
439 | if (gpio_get_value(up->rts_gpio) != res) { | 440 | if (gpio_get_value(up->rts_gpio) != res) { |
440 | gpio_set_value(up->rts_gpio, res); | 441 | gpio_set_value(up->rts_gpio, res); |
441 | if (up->rs485.delay_rts_before_send > 0) | 442 | if (port->rs485.delay_rts_before_send > 0) |
442 | mdelay(up->rs485.delay_rts_before_send); | 443 | mdelay(port->rs485.delay_rts_before_send); |
443 | } | 444 | } |
444 | } | 445 | } |
445 | 446 | ||
446 | if ((up->rs485.flags & SER_RS485_ENABLED) && | 447 | if ((port->rs485.flags & SER_RS485_ENABLED) && |
447 | !(up->rs485.flags & SER_RS485_RX_DURING_TX)) | 448 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) |
448 | serial_omap_stop_rx(port); | 449 | serial_omap_stop_rx(port); |
449 | 450 | ||
450 | serial_omap_enable_ier_thri(up); | 451 | serial_omap_enable_ier_thri(up); |
@@ -1355,16 +1356,14 @@ static inline void serial_omap_add_console_port(struct uart_omap_port *up) | |||
1355 | #endif | 1356 | #endif |
1356 | 1357 | ||
1357 | /* Enable or disable the rs485 support */ | 1358 | /* Enable or disable the rs485 support */ |
1358 | static void | 1359 | static int |
1359 | serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | 1360 | serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) |
1360 | { | 1361 | { |
1361 | struct uart_omap_port *up = to_uart_omap_port(port); | 1362 | struct uart_omap_port *up = to_uart_omap_port(port); |
1362 | unsigned long flags; | ||
1363 | unsigned int mode; | 1363 | unsigned int mode; |
1364 | int val; | 1364 | int val; |
1365 | 1365 | ||
1366 | pm_runtime_get_sync(up->dev); | 1366 | pm_runtime_get_sync(up->dev); |
1367 | spin_lock_irqsave(&up->port.lock, flags); | ||
1368 | 1367 | ||
1369 | /* Disable interrupts from this port */ | 1368 | /* Disable interrupts from this port */ |
1370 | mode = up->ier; | 1369 | mode = up->ier; |
@@ -1372,7 +1371,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
1372 | serial_out(up, UART_IER, 0); | 1371 | serial_out(up, UART_IER, 0); |
1373 | 1372 | ||
1374 | /* store new config */ | 1373 | /* store new config */ |
1375 | up->rs485 = *rs485conf; | 1374 | port->rs485 = *rs485conf; |
1376 | 1375 | ||
1377 | /* | 1376 | /* |
1378 | * Just as a precaution, only allow rs485 | 1377 | * Just as a precaution, only allow rs485 |
@@ -1380,12 +1379,12 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
1380 | */ | 1379 | */ |
1381 | if (gpio_is_valid(up->rts_gpio)) { | 1380 | if (gpio_is_valid(up->rts_gpio)) { |
1382 | /* enable / disable rts */ | 1381 | /* enable / disable rts */ |
1383 | val = (up->rs485.flags & SER_RS485_ENABLED) ? | 1382 | val = (port->rs485.flags & SER_RS485_ENABLED) ? |
1384 | SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND; | 1383 | SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND; |
1385 | val = (up->rs485.flags & val) ? 1 : 0; | 1384 | val = (port->rs485.flags & val) ? 1 : 0; |
1386 | gpio_set_value(up->rts_gpio, val); | 1385 | gpio_set_value(up->rts_gpio, val); |
1387 | } else | 1386 | } else |
1388 | up->rs485.flags &= ~SER_RS485_ENABLED; | 1387 | port->rs485.flags &= ~SER_RS485_ENABLED; |
1389 | 1388 | ||
1390 | /* Enable interrupts */ | 1389 | /* Enable interrupts */ |
1391 | up->ier = mode; | 1390 | up->ier = mode; |
@@ -1394,45 +1393,18 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
1394 | /* If RS-485 is disabled, make sure the THR interrupt is fired when | 1393 | /* If RS-485 is disabled, make sure the THR interrupt is fired when |
1395 | * TX FIFO is below the trigger level. | 1394 | * TX FIFO is below the trigger level. |
1396 | */ | 1395 | */ |
1397 | if (!(up->rs485.flags & SER_RS485_ENABLED) && | 1396 | if (!(port->rs485.flags & SER_RS485_ENABLED) && |
1398 | (up->scr & OMAP_UART_SCR_TX_EMPTY)) { | 1397 | (up->scr & OMAP_UART_SCR_TX_EMPTY)) { |
1399 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; | 1398 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
1400 | serial_out(up, UART_OMAP_SCR, up->scr); | 1399 | serial_out(up, UART_OMAP_SCR, up->scr); |
1401 | } | 1400 | } |
1402 | 1401 | ||
1403 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1404 | pm_runtime_mark_last_busy(up->dev); | 1402 | pm_runtime_mark_last_busy(up->dev); |
1405 | pm_runtime_put_autosuspend(up->dev); | 1403 | pm_runtime_put_autosuspend(up->dev); |
1406 | } | ||
1407 | |||
1408 | static int | ||
1409 | serial_omap_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | ||
1410 | { | ||
1411 | struct serial_rs485 rs485conf; | ||
1412 | |||
1413 | switch (cmd) { | ||
1414 | case TIOCSRS485: | ||
1415 | if (copy_from_user(&rs485conf, (void __user *) arg, | ||
1416 | sizeof(rs485conf))) | ||
1417 | return -EFAULT; | ||
1418 | 1404 | ||
1419 | serial_omap_config_rs485(port, &rs485conf); | ||
1420 | break; | ||
1421 | |||
1422 | case TIOCGRS485: | ||
1423 | if (copy_to_user((void __user *) arg, | ||
1424 | &(to_uart_omap_port(port)->rs485), | ||
1425 | sizeof(rs485conf))) | ||
1426 | return -EFAULT; | ||
1427 | break; | ||
1428 | |||
1429 | default: | ||
1430 | return -ENOIOCTLCMD; | ||
1431 | } | ||
1432 | return 0; | 1405 | return 0; |
1433 | } | 1406 | } |
1434 | 1407 | ||
1435 | |||
1436 | static struct uart_ops serial_omap_pops = { | 1408 | static struct uart_ops serial_omap_pops = { |
1437 | .tx_empty = serial_omap_tx_empty, | 1409 | .tx_empty = serial_omap_tx_empty, |
1438 | .set_mctrl = serial_omap_set_mctrl, | 1410 | .set_mctrl = serial_omap_set_mctrl, |
@@ -1453,7 +1425,6 @@ static struct uart_ops serial_omap_pops = { | |||
1453 | .request_port = serial_omap_request_port, | 1425 | .request_port = serial_omap_request_port, |
1454 | .config_port = serial_omap_config_port, | 1426 | .config_port = serial_omap_config_port, |
1455 | .verify_port = serial_omap_verify_port, | 1427 | .verify_port = serial_omap_verify_port, |
1456 | .ioctl = serial_omap_ioctl, | ||
1457 | #ifdef CONFIG_CONSOLE_POLL | 1428 | #ifdef CONFIG_CONSOLE_POLL |
1458 | .poll_put_char = serial_omap_poll_put_char, | 1429 | .poll_put_char = serial_omap_poll_put_char, |
1459 | .poll_get_char = serial_omap_poll_get_char, | 1430 | .poll_get_char = serial_omap_poll_get_char, |
@@ -1587,7 +1558,7 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | |||
1587 | static int serial_omap_probe_rs485(struct uart_omap_port *up, | 1558 | static int serial_omap_probe_rs485(struct uart_omap_port *up, |
1588 | struct device_node *np) | 1559 | struct device_node *np) |
1589 | { | 1560 | { |
1590 | struct serial_rs485 *rs485conf = &up->rs485; | 1561 | struct serial_rs485 *rs485conf = &up->port.rs485; |
1591 | u32 rs485_delay[2]; | 1562 | u32 rs485_delay[2]; |
1592 | enum of_gpio_flags flags; | 1563 | enum of_gpio_flags flags; |
1593 | int ret; | 1564 | int ret; |
@@ -1682,14 +1653,21 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1682 | up->port.ops = &serial_omap_pops; | 1653 | up->port.ops = &serial_omap_pops; |
1683 | 1654 | ||
1684 | if (pdev->dev.of_node) | 1655 | if (pdev->dev.of_node) |
1685 | up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); | 1656 | ret = of_alias_get_id(pdev->dev.of_node, "serial"); |
1686 | else | 1657 | else |
1687 | up->port.line = pdev->id; | 1658 | ret = pdev->id; |
1688 | 1659 | ||
1689 | if (up->port.line < 0) { | 1660 | if (ret < 0) { |
1690 | dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", | 1661 | dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", |
1691 | up->port.line); | 1662 | ret); |
1692 | ret = -ENODEV; | 1663 | goto err_port_line; |
1664 | } | ||
1665 | up->port.line = ret; | ||
1666 | |||
1667 | if (up->port.line >= OMAP_MAX_HSUART_PORTS) { | ||
1668 | dev_err(&pdev->dev, "uart ID %d > MAX %d.\n", up->port.line, | ||
1669 | OMAP_MAX_HSUART_PORTS); | ||
1670 | ret = -ENXIO; | ||
1693 | goto err_port_line; | 1671 | goto err_port_line; |
1694 | } | 1672 | } |
1695 | 1673 | ||
@@ -1702,6 +1680,7 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1702 | up->port.membase = base; | 1680 | up->port.membase = base; |
1703 | up->port.flags = omap_up_info->flags; | 1681 | up->port.flags = omap_up_info->flags; |
1704 | up->port.uartclk = omap_up_info->uartclk; | 1682 | up->port.uartclk = omap_up_info->uartclk; |
1683 | up->port.rs485_config = serial_omap_config_rs485; | ||
1705 | if (!up->port.uartclk) { | 1684 | if (!up->port.uartclk) { |
1706 | up->port.uartclk = DEFAULT_CLK_SPEED; | 1685 | up->port.uartclk = DEFAULT_CLK_SPEED; |
1707 | dev_warn(&pdev->dev, | 1686 | dev_warn(&pdev->dev, |
@@ -1747,8 +1726,6 @@ err_add_port: | |||
1747 | pm_runtime_disable(&pdev->dev); | 1726 | pm_runtime_disable(&pdev->dev); |
1748 | err_rs485: | 1727 | err_rs485: |
1749 | err_port_line: | 1728 | err_port_line: |
1750 | dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", | ||
1751 | pdev->id, __func__, ret); | ||
1752 | return ret; | 1729 | return ret; |
1753 | } | 1730 | } |
1754 | 1731 | ||