diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index e1eaa66c047b..f3ff0ca377c5 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -51,6 +51,8 @@ static void serial_omap_rxdma_poll(unsigned long uart_no); | |||
51 | static int serial_omap_start_rxdma(struct uart_omap_port *up); | 51 | static int serial_omap_start_rxdma(struct uart_omap_port *up); |
52 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); | 52 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); |
53 | 53 | ||
54 | static struct workqueue_struct *serial_omap_uart_wq; | ||
55 | |||
54 | static inline unsigned int serial_in(struct uart_omap_port *up, int offset) | 56 | static inline unsigned int serial_in(struct uart_omap_port *up, int offset) |
55 | { | 57 | { |
56 | offset <<= up->port.regshift; | 58 | offset <<= up->port.regshift; |
@@ -671,6 +673,14 @@ serial_omap_configure_xonxoff | |||
671 | serial_out(up, UART_LCR, up->lcr); | 673 | serial_out(up, UART_LCR, up->lcr); |
672 | } | 674 | } |
673 | 675 | ||
676 | static void serial_omap_uart_qos_work(struct work_struct *work) | ||
677 | { | ||
678 | struct uart_omap_port *up = container_of(work, struct uart_omap_port, | ||
679 | qos_work); | ||
680 | |||
681 | pm_qos_update_request(&up->pm_qos_request, up->latency); | ||
682 | } | ||
683 | |||
674 | static void | 684 | static void |
675 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | 685 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, |
676 | struct ktermios *old) | 686 | struct ktermios *old) |
@@ -711,6 +721,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
711 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); | 721 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); |
712 | quot = serial_omap_get_divisor(port, baud); | 722 | quot = serial_omap_get_divisor(port, baud); |
713 | 723 | ||
724 | /* calculate wakeup latency constraint */ | ||
725 | up->calc_latency = (1000000 * up->port.fifosize) / | ||
726 | (1000 * baud / 8); | ||
727 | up->latency = up->calc_latency; | ||
728 | schedule_work(&up->qos_work); | ||
729 | |||
714 | up->dll = quot & 0xff; | 730 | up->dll = quot & 0xff; |
715 | up->dlh = quot >> 8; | 731 | up->dlh = quot >> 8; |
716 | up->mdr1 = UART_OMAP_MDR1_DISABLE; | 732 | up->mdr1 = UART_OMAP_MDR1_DISABLE; |
@@ -1145,8 +1161,11 @@ static int serial_omap_suspend(struct device *dev) | |||
1145 | { | 1161 | { |
1146 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1162 | struct uart_omap_port *up = dev_get_drvdata(dev); |
1147 | 1163 | ||
1148 | if (up) | 1164 | if (up) { |
1149 | uart_suspend_port(&serial_omap_reg, &up->port); | 1165 | uart_suspend_port(&serial_omap_reg, &up->port); |
1166 | flush_work_sync(&up->qos_work); | ||
1167 | } | ||
1168 | |||
1150 | return 0; | 1169 | return 0; |
1151 | } | 1170 | } |
1152 | 1171 | ||
@@ -1383,6 +1402,13 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1383 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | 1402 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; |
1384 | } | 1403 | } |
1385 | 1404 | ||
1405 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | ||
1406 | up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | ||
1407 | pm_qos_add_request(&up->pm_qos_request, | ||
1408 | PM_QOS_CPU_DMA_LATENCY, up->latency); | ||
1409 | serial_omap_uart_wq = create_singlethread_workqueue(up->name); | ||
1410 | INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); | ||
1411 | |||
1386 | pm_runtime_use_autosuspend(&pdev->dev); | 1412 | pm_runtime_use_autosuspend(&pdev->dev); |
1387 | pm_runtime_set_autosuspend_delay(&pdev->dev, | 1413 | pm_runtime_set_autosuspend_delay(&pdev->dev, |
1388 | omap_up_info->autosuspend_timeout); | 1414 | omap_up_info->autosuspend_timeout); |
@@ -1416,6 +1442,8 @@ static int serial_omap_remove(struct platform_device *dev) | |||
1416 | if (up) { | 1442 | if (up) { |
1417 | pm_runtime_disable(&up->pdev->dev); | 1443 | pm_runtime_disable(&up->pdev->dev); |
1418 | uart_remove_one_port(&serial_omap_reg, &up->port); | 1444 | uart_remove_one_port(&serial_omap_reg, &up->port); |
1445 | pm_qos_remove_request(&up->pm_qos_request); | ||
1446 | |||
1419 | kfree(up); | 1447 | kfree(up); |
1420 | } | 1448 | } |
1421 | 1449 | ||
@@ -1518,6 +1546,9 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
1518 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | 1546 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) |
1519 | pdata->set_forceidle(up->pdev); | 1547 | pdata->set_forceidle(up->pdev); |
1520 | 1548 | ||
1549 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | ||
1550 | schedule_work(&up->qos_work); | ||
1551 | |||
1521 | return 0; | 1552 | return 0; |
1522 | } | 1553 | } |
1523 | 1554 | ||
@@ -1538,6 +1569,9 @@ static int serial_omap_runtime_resume(struct device *dev) | |||
1538 | if (up->use_dma && pdata->set_noidle && | 1569 | if (up->use_dma && pdata->set_noidle && |
1539 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | 1570 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) |
1540 | pdata->set_noidle(up->pdev); | 1571 | pdata->set_noidle(up->pdev); |
1572 | |||
1573 | up->latency = up->calc_latency; | ||
1574 | schedule_work(&up->qos_work); | ||
1541 | } | 1575 | } |
1542 | 1576 | ||
1543 | return 0; | 1577 | return 0; |